From 22cf85aa4e55ff649647b36c5455db507104cd7c Mon Sep 17 00:00:00 2001 From: Steve Brokenshire Date: Tue, 23 Aug 2016 21:41:14 +0100 Subject: [PATCH] Get etag value after adding a contact using the ConnectionObject interface --- source/actmgr/frmActivityMgr.cpp | 7 +- source/carddav2/carddav2.cpp | 232 +++++++++++++++++++++++++++++++ source/carddav2/carddav2.h | 1 + 3 files changed, 239 insertions(+), 1 deletion(-) diff --git a/source/actmgr/frmActivityMgr.cpp b/source/actmgr/frmActivityMgr.cpp index 1b63314..fef672f 100644 --- a/source/actmgr/frmActivityMgr.cpp +++ b/source/actmgr/frmActivityMgr.cpp @@ -644,9 +644,14 @@ void frmActivityMgr::ProcessTasksThread() // TODO: Get the entity tag for the new contact. + COServerResponse ETagGetResponse = ConnObjectIter->second->GetServerEntityTagValue(StringURLIter->second.ToStdString()); + if (AddContactResponse.RequestResult != COREQUEST_OK){ + iter->second = 2; + break; + } - ETagDBPtr->AddETag(ContactFilename, ETagServer, ETagServer); + ETagDBPtr->AddETag(ContactFilename, ETagGetResponse.EntityTag, ETagGetResponse.EntityTag); iter->second = 4; break; diff --git a/source/carddav2/carddav2.cpp b/source/carddav2/carddav2.cpp index 494468c..66982d9 100644 --- a/source/carddav2/carddav2.cpp +++ b/source/carddav2/carddav2.cpp @@ -839,6 +839,94 @@ COServerResponse CardDAV2::DeleteContact(std::string Location, std::string Entit COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){ + // Check if authentication was successful, otherwise don't do anything. + + COServerResponse ServerResponse; + + if (AuthPassed == false){ + ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED; + ServerResponse.EntityTag = ""; + ServerResponse.SessionCode = 0; + ServerResponse.ResultCode = 0; + ServerResponse.ResultMessage = ""; + return ServerResponse; + } + + ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true); + ResetResults(); + + static const char* GetETagQuery = + "" + "" + "" + "" + "" + ""; + + string ServerAddressURL = BuildURL(ServerPrefix + Location); + curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str()); + curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT"); + curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, GetETagQuery); + curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(GetETagQuery)); + + 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){ + ServerResponse.RequestResult = COREQUEST_ERROR_SERVER; + ServerResponse.EntityTag = ""; + ServerResponse.SessionCode = SessionResult; + ServerResponse.ResultCode = SessionResponseCode; + ServerResponse.ResultMessage = ""; + return ServerResponse; + } + + CanProcess = true; + + ServerResponse.RequestResult = COREQUEST_OK; + ServerResponse.EntityTag = GetETagValue(); + ServerResponse.SessionCode = SessionResult; + ServerResponse.ResultCode = SessionResponseCode; + ServerResponse.ResultMessage = SessionErrorBuffer; + + return ServerResponse; + } COServerResponse CardDAV2::GetContact(std::string Location){ @@ -995,6 +1083,150 @@ void CardDAV2::ResetResults(){ } +string CardDAV2::GetETagValue(){ + + xmlDocPtr xmlCardDAVDoc; + + xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0); + + xmlNodePtr nodeLevel1; + xmlNodePtr nodeLevel2; + xmlNodePtr nodeLevel3; + xmlNodePtr nodeLevel4; + xmlNodePtr nodeLevel5; + xmlNodePtr nodeLevel6; + + //std::map xmlDataMap; + + std::string DataFilename; + std::string ETagData; + + std::string xmlStringSafe; + std::string ETagValue; + + // Tranverse through the catacombs of the response to get our ETag for the file. + + for (nodeLevel1 = xmlCardDAVDoc->children; + nodeLevel1 != NULL; + nodeLevel1 = nodeLevel1->next) + { + + bool HREFFound = FALSE; + bool ETagFound = FALSE; + + for (nodeLevel2 = nodeLevel1->children; + nodeLevel2 != NULL; + nodeLevel2 = nodeLevel2->next) + { + + for (nodeLevel3 = nodeLevel2->children; + nodeLevel3 != NULL; + nodeLevel3 = nodeLevel3->next) + { + + if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") || + !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href") + ){ + + // Get the filename. + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") || + !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text") + ){ + + DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content); + wxStringTokenizer wSTDFilename(DataFilename, wxT("/")); + + while (wSTDFilename.HasMoreTokens()){ + + DataFilename = wSTDFilename.GetNextToken().ToStdString(); + + } + + HREFFound = TRUE; + + } + + + + } + + } else { + + for (nodeLevel4 = nodeLevel3->children; + nodeLevel4 != NULL; + nodeLevel4 = nodeLevel4->next) + { + + for (nodeLevel5 = nodeLevel4->children; + nodeLevel5 != NULL; + nodeLevel5 = nodeLevel5->next) + { + + if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") || + !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag") + ){ + + for (nodeLevel6 = nodeLevel5->children; + nodeLevel6 != NULL; + nodeLevel6 = nodeLevel6->next) + { + + // Strip the quotes from the ETag. + + ETagData = (const char*)nodeLevel6->content; + if (ETagData[0] == '"' && ETagData[(ETagData.size() - 1)] == '"'){ + + ETagData.erase(0, 1); + ETagData.erase((ETagData.size() - 1)); + + } + + ETagFound = TRUE; + + } + + } + + } + + } + + } + + } + + } + + if (HREFFound == TRUE && ETagFound == TRUE){ + + // Add to the map data. + + ETagValue = ETagData; + + HREFFound = FALSE; + ETagFound = FALSE; + break; + + } + + + } + + xmlFreeDoc(xmlCardDAVDoc); + + return ETagValue; + +} + string CardDAV2::GetETagHeader(){ // Go through each of the lines looking for the diff --git a/source/carddav2/carddav2.h b/source/carddav2/carddav2.h index 3828d07..729b24b 100644 --- a/source/carddav2/carddav2.h +++ b/source/carddav2/carddav2.h @@ -99,6 +99,7 @@ class CardDAV2 : public ConnectionObject { void ResetResults(); std::vector GetDAVHeader(); std::string GetETagHeader(); + std::string GetETagValue(); std::string GetUserPrincipalURI(); std::string GetAddressBookHomeURI(); -- 2.39.2