Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Implemented GetContactList in CardDAV2 class
authorSteve Brokenshire <sbrokenshire@xestia.co.uk>
Sun, 4 Sep 2016 19:36:23 +0000 (20:36 +0100)
committerSteve Brokenshire <sbrokenshire@xestia.co.uk>
Sun, 4 Sep 2016 19:36:23 +0000 (20:36 +0100)
source/carddav2/carddav2.cpp
source/carddav2/carddav2.h

index 1d8f632..536afac 100644 (file)
@@ -1172,6 +1172,126 @@ COServerResponse CardDAV2::GetContact(std::string Location, std::string *Contact
 
 COContactList CardDAV2::GetContactList(std::string SyncToken){
        
+       COContactList ServerContactList;
+       
+       // Check if authentication was successful, otherwise don't do anything.
+       
+       if (AuthPassed == false){
+               ServerContactList.ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
+               ServerContactList.ServerResponse.EntityTag = "";
+               ServerContactList.ServerResponse.SessionCode = 0;
+               ServerContactList.ServerResponse.ResultCode = 0;
+               ServerContactList.ServerResponse.ResultMessage = "";
+               return ServerContactList;
+       }
+
+       ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
+       ResetResults();
+       
+       std::string SyncData;
+       
+       // TODO: Copy old code from CardDAV class as needed.
+       
+       if (SyncToken.size() > 0){
+               
+               SyncData = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+               "<D:sync-collection xmlns:D=\"DAV:\"\n"
+               " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+               "<D:sync-token>";
+               SyncData.append(SyncToken);
+               SyncData.append("</D:sync-token>\n"
+               "<D:sync-level>1</D:sync-level>\n"
+               "<D:prop>\n"
+               "       <D:getetag/>\n"
+               "</D:prop>\n"
+               "</D:sync-collection>");
+       
+       } else {
+               
+               SyncData = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+               "<D:sync-collection xmlns:D=\"DAV:\"\n"
+               " xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
+               "<D:sync-level>1</D:sync-level>\n"
+               "<D:prop>\n"
+               "       <D:getetag/>\n"
+               "</D:prop>\n"
+               "</D:sync-collection>";
+
+       }
+       
+       string ServerAddressURL = BuildURL(ServerPrefix);
+       
+       std::cout << SyncData << std::endl;
+       
+       curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, SyncData.c_str());
+       curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(SyncData.c_str()));
+       curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT");
+       
+       HeaderList = curl_slist_append(HeaderList, "Content-Type: application/xml; charset=utf-8");
+       HeaderList = curl_slist_append(HeaderList, "Depth: 1");
+
+       curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
+       
+       if (TestMode == true){
+               SessionResult = curl_easy_perform(ConnectionSession);
+       } else {
+               SessionResult = curl_easy_perform(ConnectionSession);
+       }
+       
+       switch(SessionResult){
+               case CURLE_OK:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_VERIFIED;
+                       break;
+               case CURLE_SSL_CACERT:
+               case CURLE_SSL_CONNECT_ERROR:
+                       SSLStatus = true;
+                       SSLVerified = COSSL_UNABLETOVERIFY;
+                       break;
+               default:
+                       break;
+       };
+       
+       long SessionResponseCode = 0;
+       
+       curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
+       
+       if (SessionResponseCode == 207){
+               AuthPassed = true;
+               ValidResponse = true;
+       } else if (SessionResponseCode == 403){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else if (SessionResponseCode >= 400){
+               AuthPassed = false;
+               ValidResponse = true;
+       } else {
+               AuthPassed = false;
+               ValidResponse = false;                  
+       }
+       
+       if (ValidResponse == false || AuthPassed == false){
+               ServerContactList.ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
+               ServerContactList.ServerResponse.EntityTag = "";
+               ServerContactList.ServerResponse.SessionCode = SessionResult;
+               ServerContactList.ServerResponse.ResultCode = SessionResponseCode;
+               ServerContactList.ServerResponse.ResultMessage = "";
+               return ServerContactList;
+       }
+       
+       CanProcess = true;
+       
+       ProcessContactData(&ServerContactList);
+       
+       ServerContactList.ServerResponse.RequestResult = COREQUEST_OK;
+       ServerContactList.ServerResponse.EntityTag = "";
+       ServerContactList.ServerResponse.SessionCode = SessionResult;
+       ServerContactList.ServerResponse.ResultCode = SessionResponseCode;
+       ServerContactList.ServerResponse.ResultMessage = SessionErrorBuffer;
+       
+       return ServerContactList;
+       
 }
        
 bool CardDAV2::CanDoProcessing(){
@@ -1630,4 +1750,163 @@ vector<string> CardDAV2::GetDAVHeader(){
        
        return DAVHeaderList;
        
+}
+
+void CardDAV2::ProcessContactData(COContactList *ContactList){
+       
+       xmlDocPtr xmlCardDAVDoc;
+       xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
+
+       xmlNodePtr MultiStatusNode;
+       xmlNodePtr ResponseNode;
+       xmlNodePtr ResponseDataNode;
+       xmlNodePtr PropStatNode;
+       xmlNodePtr ValueNode;
+       xmlNodePtr ETagNode;
+       xmlNodePtr StatusNode;
+
+       std::string HREFValue;
+       std::string ETagValue;
+       std::string StatusValue;
+       std::string SyncValue;
+
+       // Go through the document!
+
+       MultiStatusNode = xmlCardDAVDoc->children;
+
+       if (MultiStatusNode == nullptr){
+               return;
+       }
+
+       bool SyncTokenFound = false;
+
+       // Tranverse through the catacombs of the response to get our ETag for the file and
+       // the server syncronisation token.
+       
+       for (ResponseNode = MultiStatusNode->children;
+               ResponseNode != nullptr;
+               ResponseNode = ResponseNode->next){
+
+               // Check if tag is response or sync-token.
+
+               if (!xmlStrcmp(ResponseNode->name, (const xmlChar *)"response") ||
+               !xmlStrcmp(ResponseNode->name, (const xmlChar *)"d:response") ||
+               !xmlStrcmp(ResponseNode->name, (const xmlChar *)"D:response")){
+
+                       COContactStatus ContactStatus = COCS_UNKNOWN;
+                       
+                       for (ResponseDataNode = ResponseNode->children;
+                               ResponseDataNode != nullptr;
+                               ResponseDataNode = ResponseDataNode->next){
+
+                               if (!xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"href") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"d:href") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"D:href")){
+                               
+                                       HREFValue = (const char*)ResponseDataNode->children->content;
+
+                                       // Get the filename after the last forward slash.
+                                       
+                                       int LastSlash = 0;
+                                       
+                                       for (int HREFValueSeek = 0; HREFValueSeek < HREFValue.size(); HREFValueSeek++){
+                                               
+                                               if (HREFValue[HREFValueSeek] == '/'){
+                                               
+                                                       LastSlash = HREFValueSeek;
+                                                       
+                                               }
+                                               
+                                       }
+                                       
+                                       HREFValue = HREFValue.substr((LastSlash + 1));
+                                       
+                               } else if (!xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"propstat") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"d:propstat") ||
+                               !xmlStrcmp(ResponseDataNode->name, (const xmlChar *)"D:propstat")){
+
+                                       for (PropStatNode = ResponseDataNode->children;
+                                               PropStatNode != nullptr;
+                                               PropStatNode = PropStatNode->next){
+
+                                               if (!xmlStrcmp(PropStatNode->name, (const xmlChar *)"prop") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"d:prop") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"D:prop")){
+
+                                                       for (ETagNode = PropStatNode->children;
+                                                               ETagNode != nullptr;
+                                                               ETagNode = ETagNode->next){
+
+                                                                       if (!xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag") ||
+                                                                       !xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag") ||
+                                                                       !xmlStrcmp(ETagNode->name, (const xmlChar *)"getetag")){
+
+                                                                               ETagValue = (const char*)ETagNode->children->content;
+
+                                                                               if (ETagValue.size() > 2 && ETagValue.substr(0,1) == "\""){
+                                                                                       ETagValue.erase((ETagValue.size() - 1),1);
+                                                                                       ETagValue.erase(0,1);
+                                                                               }
+
+                                                                       }
+                                                       
+
+                                                       }
+
+                                               } else if (!xmlStrcmp(PropStatNode->name, (const xmlChar *)"status") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"d:status") ||
+                                                       !xmlStrcmp(PropStatNode->name, (const xmlChar *)"D:status")){
+
+                                                       StatusValue = (const char*)PropStatNode->children->content;
+
+                                                       if (StatusValue == "HTTP/1.1 200 OK"){
+
+                                                               ContactStatus = COCS_UPDATED;
+
+                                                       } else if (StatusValue == "HTTP/1.1 404 Not Found"){
+
+                                                               ContactStatus = COCS_DELETED;
+
+                                                       } else {
+
+                                                               ContactStatus = COCS_UNKNOWN;
+
+                                                       }
+
+                                               }
+
+                                       }
+
+                               }
+
+                       }
+
+                       COContactData ContactInformation;
+                       
+                       ContactInformation.Location = HREFValue;
+                       ContactInformation.Data = ETagValue;
+                       ContactInformation.Status = ContactStatus;
+
+                       HREFValue.clear();
+                       ETagValue.clear();
+                       StatusValue.clear();
+                       
+                       ContactList->ListData.push_back(ContactInformation);
+
+               } else if (!xmlStrcmp(ResponseNode->name, (const xmlChar *)"sync-token") ||
+                       !xmlStrcmp(ResponseNode->name, (const xmlChar *)"d:sync-token") ||
+                       !xmlStrcmp(ResponseNode->name, (const xmlChar *)"D:sync-token")){
+
+                       SyncValue = (const char*)ResponseNode->children->content;
+
+               }
+
+       }
+
+       ContactList->SyncToken = SyncValue;
+
+       xmlFreeDoc(xmlCardDAVDoc);
+
+       return;
+       
 }
\ No newline at end of file
index ceca5c2..2698d5a 100644 (file)
@@ -104,6 +104,7 @@ class CardDAV2 : public ConnectionObject {
                std::string GetUserPrincipalURI();
                std::string GetAddressBookHomeURI();
                std::string GetDefaultAddressBookURI();
+               void ProcessContactData(COContactList *ContactList);
        
 #if defined(__APPLE__)
 #elif defined(__WIN32__)
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy