Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Implemented EditContact and GetContact in CardDAV2
[xestiaab/.git] / source / carddav2 / carddav2.cpp
1 // CardDAV2.cpp - CardDAV v2 class
2 //
3 // (c) 2012-2016 Xestia Software Development.
4 //
5 // This file is part of Xestia Address Book.
6 //
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
10 //
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/> 
19 #include "carddav2.h"
21 #include <iostream>
23 using namespace std;
25 size_t CardDAV2::WritebackFunc(char *ptr, size_t size, size_t nmemb, void *stream){
26         
27         return static_cast<CardDAV2*>(stream)->WritebackFuncImplementation(ptr, size, nmemb, stream);
28         
29 }
30         
31 size_t CardDAV2::WritebackFuncImplementation(char *ptr, size_t size, size_t nmemb, void *stream){
32         
33         // Writeback function for the CardDAV object.
34                 
35         string *data = static_cast<string*>(stream);
36         data->append(ptr);
37         
38         // Get the SSL engine pointer and trust if required on certain operating systems.
39         
40         if (ServerSSL){
41         
42 #if defined(__APPLE__)
43         
44                 const struct curl_tlssessioninfo *TLSInfo;
45                 CURLcode TLSCode;
46                 CURL *Connection = GetConnectionObject();
47                 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
48         
49                 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
50                         SSLCopyPeerTrust((SSLContext*)TLSInfo->internals, &SecTrustObject);
51                 }
52         
53 #elif defined(__WIN32__)
55                 const struct curl_tlssessioninfo *TLSInfo;
56                 CURLcode TLSCode;
57                 CURL *Connection = GetConnectionObject();
58                 TLSCode = curl_easy_getinfo(Connection, CURLINFO_TLS_SSL_PTR, &TLSInfo);
60                 if (TLSInfo->internals != nullptr && TLSCode == CURLE_OK){
62                         // Free the previous certificate data.
64                         CertFreeCertificateContext(CertificateData);
66                         PCtxtHandle SSLHandle = (PCtxtHandle)TLSInfo->internals;
67                         SECURITY_STATUS GetData = QueryContextAttributes(SSLHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &CertificateData);
69                 }
71 #endif
73         }
74         
75         return size * nmemb;
77 }
79 CardDAV2::~CardDAV2(){
80         
81         curl_easy_cleanup(ConnectionSession);
82         ConnectionSession = nullptr;
83         
84         if (HeaderList != nullptr){
85                 curl_slist_free_all(HeaderList);
86                 HeaderList = nullptr;
87         }
88         
89 }
91 #if defined(__APPLE__)
93 #elif defined(__WIN32__)
95 #else
97 SSLCertCollectionString CardDAV2::BuildSSLCollection(){
99         // Build and return the SSL collection.
100         
101         SSLCertCollectionString SSLCertInfo;
103         // Grab the certificate data.
105         union {
106                 struct curl_slist *certdata;
107                 struct curl_certinfo *certinfo;
108         } certptr;
110         certptr.certdata = NULL;
111         
112         curl_easy_getinfo(ConnectionSession, CURLINFO_CERTINFO, &certptr.certinfo);
114         std::string CertPropName;
115         std::string CertPropValue;
117         for (int i = 0; i < certptr.certinfo->num_of_certs; i++){
119                 struct curl_slist *slist;
120                 SSLCertDataString SSLCertDataInc;
121                 
122                 for (slist = certptr.certinfo->certinfo[i]; slist; slist = slist->next){
123                         
124                         // Using wxStringTokenizer from wxWidgets.
125                         
126                         wxStringTokenizer CertDataInc(wxString::FromUTF8(slist->data), ":");
127                         
128                         // Get first token as the property name.
129                         
130                         CertPropName = CertDataInc.GetNextToken().ToStdString();
131                         
132                         // Get remaining tokens as the property value.
133                         
134                         while(CertDataInc.HasMoreTokens()){
135                         
136                                 CertPropValue.append(CertDataInc.GetNextToken());
137                         
138                         }
139                         
140                         SSLCertDataInc.CertData.insert(std::make_pair(CertPropName, CertPropValue));
141                         CertPropName.clear();
142                         CertPropValue.clear();
143                         
144                 }
145         
146                 SSLCertInfo.SSLCollection.insert(std::make_pair(i, SSLCertDataInc));
147         
148         }
149         
150         return SSLCertInfo;
154 void CardDAV2::BypassSSLVerification(bool EnableBypass){
155         EnableSSLBypass = EnableBypass;
156         SSLSelfSigned = EnableBypass;
159 #endif
161 void CardDAV2::SetupConnectionObject(){
162         ConnectionSession = curl_easy_init();
165 bool CardDAV2::IsTaskCompleted(){
166         return false;
169 COConnectResult CardDAV2::Connect(bool DoAuthentication){
170         
171         ServerSSL ? SetupDefaultParametersSSL(DoAuthentication) : SetupDefaultParametersNonSSL(DoAuthentication);
172         ResetResults();
173         
174         COConnectResult ConnectResult = COCONNECT_UNITTESTFAIL;
175         string ServerAddressURL = BuildURL("/principals/");
177         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
178         
179         if (TestMode == true){
180                 SessionResult = curl_easy_perform(ConnectionSession);
181         } else {
182                 SessionResult = curl_easy_perform(ConnectionSession);           
183         }
184         
185         switch(SessionResult){
186                 case CURLE_OK:
187                 case CURLE_HTTP_RETURNED_ERROR:
188                         SSLStatus = true;
189                         SSLVerified = COSSL_VERIFIED;
190                         ConnectResult = COCONNECT_OK;
191                         break;
192                 case CURLE_SSL_CACERT:
193                 case CURLE_SSL_CONNECT_ERROR:
194                         SSLStatus = true;
195                         ConnectResult = COCONNECT_OK;
196                         SSLVerified = COSSL_UNABLETOVERIFY;
197                         break;
198                 default:
199                         ConnectResult = COCONNECT_INVALID;
200                         break;
201         };
202         
203         // Check if an error occured before continuing.
204         
205         // Check if authentication was successful.
206         
207         long SessionResponseCode = 0;
208         
209         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
210         
211         if (DoAuthentication == true){
212                 
213                 // Get the HTTP status code (Should be 200 and not 403).
214                 // Return error otherwise.
215                 
216                 if (SessionResponseCode == 200){
217                         ConnectResult = COCONNECT_OK;
218                         AuthPassed = true;
219                         ValidResponse = true;
220                 } else if (SessionResponseCode == 401){
221                         ConnectResult = COCONNECT_AUTHFAIL;
222                         AuthPassed = false;
223                         ValidResponse = true;
224                 } else if (SessionResponseCode >= 200) {
225                         ConnectResult = COCONNECT_INVALID;
226                         AuthPassed = false;
227                         ValidResponse = true;
228                 } else {
229                         ConnectResult = COCONNECT_INVALID;
230                         AuthPassed = false;
231                         ValidResponse = false;                  
232                 }
233                 
234         } else {
235                 
236                 ValidResponse = true;
237                 
238         }
239         
240         // Check the header to see if CardDAV is supported.
241         
242         vector<string> DAVHeaderValues = GetDAVHeader();
243         
244         for (vector<string>::iterator DAVHeaderValuesIter = DAVHeaderValues.begin();
245                 DAVHeaderValuesIter != DAVHeaderValues.end(); DAVHeaderValuesIter++){
246                 
247                 if ((*DAVHeaderValuesIter) == "addressbook"){
248                         CanProcess = true;
249                         break;
250                 }
251                         
252         }
253         
254         return ConnectResult;
255         
258 COServerResponse CardDAV2::GetDefaultPrefix(string *ServerPrefix){
260         // Check if authentication was successful, otherwise don't do anything.
262         COServerResponse ServerResponse;
263         
264         if (AuthPassed == false){
265                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
266                 ServerResponse.EntityTag = "";
267                 ServerResponse.SessionCode = 0;
268                 ServerResponse.ResultCode = 0;
269                 ServerResponse.ResultMessage = "";
270                 return ServerResponse;
271         }
273         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
274         ResetResults();
275         
276         // Need to do three requests:
277         
278         // 1. Get the current user principal URI.
279         // 2. Get the address book home URI.
280         // 3. Get the default address book URI.
281         
282         // Setup the first query finding out where the principal URL is.
283         
284         const char* CurrentUserPrincipalXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
285                 "<D:propfind xmlns:D=\"DAV:\">\n"
286                 " <D:prop>"
287                 "  <D:current-user-principal/>\n"
288                 " </D:prop>"
289                 "</D:propfind>";
291         // Setup the second query finding out where the address book home URL is.
292         
293         const char* AddressBookHomeXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
294         "<D:propfind xmlns:D=\"DAV:\""
295         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
296         "  <D:prop>\n"
297         "    <C:addressbook-home-set/>\n"
298         "  </D:prop>\n"
299         "</D:propfind>";
300         
301         // Setup the third query finding out where the default address book URL is.
302         
303         const char* DefaultAddressBookXMLQuery = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
304         "<D:propfind xmlns:D=\"DAV:\""
305         "  xmlns:C=\"urn:ietf:params:xml:ns:carddav\">\n"
306         "  <D:prop>\n"
307         "    <C:default-addressbook-URL/>\n"    
308         "  </D:prop>\n"
309         "</D:propfind>";
310         
311         string ServerAddressURL = BuildURL("/principals/");
312         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
313         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
314         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, CurrentUserPrincipalXMLQuery);
315         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(CurrentUserPrincipalXMLQuery));
316         
317         if (TestMode == true){
318                 SessionResult = curl_easy_perform(ConnectionSession);
319         } else {
320                 
321         }
322         
323         switch(SessionResult){
324                 case CURLE_OK:
325                         SSLStatus = true;
326                         SSLVerified = COSSL_VERIFIED;
327                         break;
328                 case CURLE_SSL_CACERT:
329                 case CURLE_SSL_CONNECT_ERROR:
330                         SSLStatus = true;
331                         SSLVerified = COSSL_UNABLETOVERIFY;
332                         break;
333                 default:
334                         break;
335         };
336         
337         long SessionResponseCode = 0;
338         
339         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
340         
341         if (SessionResponseCode == 200 || SessionResponseCode == 207){
342                 AuthPassed = true;
343                 ValidResponse = true;
344         } else if (SessionResponseCode == 403){
345                 AuthPassed = false;
346                 ValidResponse = true;
347         } else if (SessionResponseCode >= 400) {
348                 AuthPassed = false;
349                 ValidResponse = true;
350         } else {
351                 AuthPassed = false;
352                 ValidResponse = false;                  
353         }
354         
355         if (ValidResponse == false && AuthPassed == false){
356                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
357                 ServerResponse.EntityTag = "";
358                 ServerResponse.SessionCode = SessionResult;
359                 ServerResponse.ResultCode = SessionResponseCode;
360                 ServerResponse.ResultMessage = "";
361                 return ServerResponse;
362         }
363         
364         // Process the first response.
365         
366         string UserPrincipalURI = GetUserPrincipalURI();
367         
368         // Cleanup and reset for the second connection.
369         
370         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
371         ResetResults();
373         ServerAddressURL = BuildURL(UserPrincipalURI);
374         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
375         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
376         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, AddressBookHomeXMLQuery);
377         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(AddressBookHomeXMLQuery));
378         
379         if (TestMode == true){
380                 SessionResult = curl_easy_perform(ConnectionSession);
381         } else {
382                 
383         }
384         
385         switch(SessionResult){
386                 case CURLE_OK:
387                         SSLStatus = true;
388                         SSLVerified = COSSL_VERIFIED;
389                         break;
390                 case CURLE_SSL_CACERT:
391                 case CURLE_SSL_CONNECT_ERROR:
392                         SSLStatus = true;
393                         SSLVerified = COSSL_UNABLETOVERIFY;
394                         break;
395                 default:
396                         break;
397         };
398         
399         SessionResponseCode = 0;
400         
401         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
402         
403         if (SessionResponseCode == 200 || SessionResponseCode == 207){
404                 AuthPassed = true;
405                 ValidResponse = true;
406         } else if (SessionResponseCode == 403){
407                 AuthPassed = false;
408                 ValidResponse = true;
409         } else if (SessionResponseCode >= 400) {
410                 AuthPassed = false;
411                 ValidResponse = true;
412         } else {
413                 AuthPassed = false;
414                 ValidResponse = false;                  
415         }
416         
417         if (ValidResponse == false && AuthPassed == false){
418                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
419                 ServerResponse.EntityTag = "";
420                 ServerResponse.SessionCode = SessionResult;
421                 ServerResponse.ResultCode = SessionResponseCode;
422                 ServerResponse.ResultMessage = "";
423                 return ServerResponse;
424         }
425         
426         // Process the second response.
427         
428         string AddressBookHomeURI = GetAddressBookHomeURI();
429         
430         // Cleanup and reset for the second connection.
431         
432         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
433         ResetResults();
434         
435         ServerAddressURL = BuildURL(AddressBookHomeURI);
436         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
437         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PROPFIND");
438         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, DefaultAddressBookXMLQuery);
439         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(DefaultAddressBookXMLQuery));
440         
441         if (TestMode == true){
442                 SessionResult = curl_easy_perform(ConnectionSession);
443         } else {
444                 
445         }
446         
447         switch(SessionResult){
448                 case CURLE_OK:
449                         SSLStatus = true;
450                         SSLVerified = COSSL_VERIFIED;
451                         break;
452                 case CURLE_SSL_CACERT:
453                 case CURLE_SSL_CONNECT_ERROR:
454                         SSLStatus = true;
455                         SSLVerified = COSSL_UNABLETOVERIFY;
456                         break;
457                 default:
458                         break;
459         };
460         
461         SessionResponseCode = 0;
462         
463         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
464         
465         if (SessionResponseCode == 200 || SessionResponseCode == 207){
466                 AuthPassed = true;
467                 ValidResponse = true;
468         } else if (SessionResponseCode == 403){
469                 AuthPassed = false;
470                 ValidResponse = true;
471         } else if (SessionResponseCode >= 200) {
472                 AuthPassed = false;
473                 ValidResponse = true;
474         } else {
475                 AuthPassed = false;
476                 ValidResponse = false;                  
477         }
478         
479         if (ValidResponse == false || AuthPassed == false){
480                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
481                 ServerResponse.EntityTag = "";
482                 ServerResponse.SessionCode = SessionResult;
483                 ServerResponse.ResultCode = SessionResponseCode;
484                 ServerResponse.ResultMessage = "";
485                 return ServerResponse;
486         }
487         
488         // Process the second response.
489         
490         (*ServerPrefix) = GetDefaultAddressBookURI();
491         
492         CanProcess = true;
493         
494         ServerResponse.RequestResult = COREQUEST_OK;
495         ServerResponse.EntityTag = "";
496         ServerResponse.SessionCode = SessionResult;
497         ServerResponse.ResultCode = SessionResponseCode;
498         ServerResponse.ResultMessage = SessionErrorBuffer;
499         return ServerResponse;
500         
503 std::string CardDAV2::GetUserPrincipalURI(){
504         
505         xmlDocPtr xmlCardDAVDoc;
506         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
507         string UserPrincipalURI = "";
508         
509         xmlNodePtr nodeLevel1;
510         xmlNodePtr nodeLevel2;
511         xmlNodePtr nodeLevel3;
512         xmlNodePtr nodeLevel4;
513         xmlNodePtr nodeLevel5;
514         xmlNodePtr nodeLevel6;
515         xmlNodePtr nodeLevel7;
516                 
517         for (nodeLevel1 = xmlCardDAVDoc->children;
518                 nodeLevel1 != NULL;
519                 nodeLevel1 = nodeLevel1->next)
520         {
522                 for (nodeLevel2 = nodeLevel1->children;
523                         nodeLevel2 != NULL;
524                         nodeLevel2 = nodeLevel2->next)
525                 {
528                         for (nodeLevel3 = nodeLevel2->children;
529                         nodeLevel3 != NULL;
530                         nodeLevel3 = nodeLevel3->next)
531                         {
532                         
533                                 for (nodeLevel4 = nodeLevel3->children;
534                                 nodeLevel4 != NULL;
535                                 nodeLevel4 = nodeLevel4->next)
536                                 {
537                         
538                                         for (nodeLevel5 = nodeLevel4->children;
539                                         nodeLevel5 != NULL;
540                                         nodeLevel5 = nodeLevel5->next)
541                                         {
542                         
543                                                 for (nodeLevel6 = nodeLevel5->children;
544                                                 nodeLevel6 != NULL;
545                                                 nodeLevel6 = nodeLevel6->next)
546                                                 {
547                         
548                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
549                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
550                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
551                                                         ){
552                         
553                                                                 // Found the <href> part so extract the principal URL address.
554                                                                 
555                                                                 for (nodeLevel7 = nodeLevel6->children;
556                                                                 nodeLevel7 != NULL;
557                                                                 nodeLevel7 = nodeLevel7->next)
558                                                                 {
559                                                                 
560                                                                         UserPrincipalURI = ((const char*)nodeLevel7->content);
562                                                                 }
563                         
564                                                         }
565                         
566                                                 }
567                         
568                                         }
569                         
570                                 }
571                         
572                         }
573                 
574                 }
575                 
576         }
577         
578         xmlFreeDoc(xmlCardDAVDoc);
579         
580         return UserPrincipalURI;
581         
584 std::string CardDAV2::GetAddressBookHomeURI(){
585         
586         xmlDocPtr xmlCardDAVDoc;
587         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
588         string AddressBookHomeURI = "";
589         
590         xmlNodePtr nodeLevel1;
591         xmlNodePtr nodeLevel2;
592         xmlNodePtr nodeLevel3;
593         xmlNodePtr nodeLevel4;
594         xmlNodePtr nodeLevel5;
595         xmlNodePtr nodeLevel6;
596         xmlNodePtr nodeLevel7;
597                 
598         for (nodeLevel1 = xmlCardDAVDoc->children;
599                 nodeLevel1 != NULL;
600                 nodeLevel1 = nodeLevel1->next)
601         {
603                 for (nodeLevel2 = nodeLevel1->children;
604                         nodeLevel2 != NULL;
605                         nodeLevel2 = nodeLevel2->next)
606                 {
609                         for (nodeLevel3 = nodeLevel2->children;
610                         nodeLevel3 != NULL;
611                         nodeLevel3 = nodeLevel3->next)
612                         {
613                         
614                                 for (nodeLevel4 = nodeLevel3->children;
615                                 nodeLevel4 != NULL;
616                                 nodeLevel4 = nodeLevel4->next)
617                                 {
618                         
619                                         for (nodeLevel5 = nodeLevel4->children;
620                                         nodeLevel5 != NULL;
621                                         nodeLevel5 = nodeLevel5->next)
622                                         {
623                         
624                                                 for (nodeLevel6 = nodeLevel5->children;
625                                                 nodeLevel6 != NULL;
626                                                 nodeLevel6 = nodeLevel6->next)
627                                                 {
628                         
629                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
630                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
631                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
632                                                         ){
633                         
634                                                                 // Found the <href> part so extract the principal URL address.
635                                                                 
636                                                                 for (nodeLevel7 = nodeLevel6->children;
637                                                                 nodeLevel7 != NULL;
638                                                                 nodeLevel7 = nodeLevel7->next)
639                                                                 {
640                                                                 
641                                                                         AddressBookHomeURI = ((const char*)nodeLevel7->content);
643                                                                 }
644                         
645                                                         }
646                         
647                                                 }
648                         
649                                         }
650                         
651                                 }
652                         
653                         }
654                 
655                 }
656                 
657         }
658         
659         xmlFreeDoc(xmlCardDAVDoc);
660         
661         return AddressBookHomeURI;
662         
665 std::string CardDAV2::GetDefaultAddressBookURI(){
666         
667         xmlDocPtr xmlCardDAVDoc;
668         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
669         string DefaultAddressBookURI = "";
670         
671         xmlNodePtr nodeLevel1;
672         xmlNodePtr nodeLevel2;
673         xmlNodePtr nodeLevel3;
674         xmlNodePtr nodeLevel4;
675         xmlNodePtr nodeLevel5;
676         xmlNodePtr nodeLevel6;
677         xmlNodePtr nodeLevel7;
678                 
679         for (nodeLevel1 = xmlCardDAVDoc->children;
680                 nodeLevel1 != NULL;
681                 nodeLevel1 = nodeLevel1->next)
682         {
684                 for (nodeLevel2 = nodeLevel1->children;
685                         nodeLevel2 != NULL;
686                         nodeLevel2 = nodeLevel2->next)
687                 {
690                         for (nodeLevel3 = nodeLevel2->children;
691                         nodeLevel3 != NULL;
692                         nodeLevel3 = nodeLevel3->next)
693                         {
694                         
695                                 for (nodeLevel4 = nodeLevel3->children;
696                                 nodeLevel4 != NULL;
697                                 nodeLevel4 = nodeLevel4->next)
698                                 {
699                         
700                                         for (nodeLevel5 = nodeLevel4->children;
701                                         nodeLevel5 != NULL;
702                                         nodeLevel5 = nodeLevel5->next)
703                                         {
704                         
705                                                 for (nodeLevel6 = nodeLevel5->children;
706                                                 nodeLevel6 != NULL;
707                                                 nodeLevel6 = nodeLevel6->next)
708                                                 {
709                         
710                                                         if (!xmlStrcmp(nodeLevel6->name, (const xmlChar *)"href") ||
711                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"d:href") ||
712                                                         !xmlStrcmp(nodeLevel6->name, (const xmlChar *)"D:href")
713                                                         ){
714                         
715                                                                 // Found the <href> part so extract the principal URL address.
716                                                                 
717                                                                 for (nodeLevel7 = nodeLevel6->children;
718                                                                 nodeLevel7 != NULL;
719                                                                 nodeLevel7 = nodeLevel7->next)
720                                                                 {
721                                                                 
722                                                                         DefaultAddressBookURI = ((const char*)nodeLevel7->content);
724                                                                 }
725                         
726                                                         }
727                         
728                                                 }
729                         
730                                         }
731                         
732                                 }
733                         
734                         }
735                 
736                 }
737                 
738         }
739         
740         xmlFreeDoc(xmlCardDAVDoc);
741         
742         return DefaultAddressBookURI;
743         
746 COServerResponse CardDAV2::AddContact(std::string Location, std::string Data){
747         
748         // Check if authentication was successful, otherwise don't do anything.
750         COServerResponse ServerResponse;
751         
752         if (AuthPassed == false){
753                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
754                 ServerResponse.EntityTag = "";
755                 ServerResponse.SessionCode = 0;
756                 ServerResponse.ResultCode = 0;
757                 ServerResponse.ResultMessage = "";
758                 return ServerResponse;
759         }
761         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
762         ResetResults();
763         
764         string ServerAddressURL = BuildURL(ServerPrefix + Location);
765         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
766         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PUT");
767         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, Data.c_str());
768         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(Data.c_str()));
769         
770         HeaderList = curl_slist_append(HeaderList, "Content-Type: text/vcard; charset=utf-8");
772         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
773         
774         if (TestMode == true){
775                 SessionResult = curl_easy_perform(ConnectionSession);
776         } else {
777                 SessionResult = curl_easy_perform(ConnectionSession);
778         }
779         
780         switch(SessionResult){
781                 case CURLE_OK:
782                         SSLStatus = true;
783                         SSLVerified = COSSL_VERIFIED;
784                         break;
785                 case CURLE_SSL_CACERT:
786                 case CURLE_SSL_CONNECT_ERROR:
787                         SSLStatus = true;
788                         SSLVerified = COSSL_UNABLETOVERIFY;
789                         break;
790                 default:
791                         break;
792         };
793         
794         long SessionResponseCode = 0;
795         
796         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
797         
798         if (SessionResponseCode == 200 || SessionResponseCode == 201 || SessionResponseCode == 204){
799                 AuthPassed = true;
800                 ValidResponse = true;
801         } else if (SessionResponseCode == 403){
802                 AuthPassed = false;
803                 ValidResponse = true;
804         } else if (SessionResponseCode >= 400){
805                 AuthPassed = false;
806                 ValidResponse = true;
807         } else {
808                 AuthPassed = false;
809                 ValidResponse = false;                  
810         }
811         
812         if (ValidResponse == false || AuthPassed == false){
813                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
814                 ServerResponse.EntityTag = "";
815                 ServerResponse.SessionCode = SessionResult;
816                 ServerResponse.ResultCode = SessionResponseCode;
817                 ServerResponse.ResultMessage = "";
818                 return ServerResponse;
819         }
820         
821         CanProcess = true;
822         
823         ServerResponse.RequestResult = COREQUEST_OK;
824         ServerResponse.EntityTag = "";
825         ServerResponse.SessionCode = SessionResult;
826         ServerResponse.ResultCode = SessionResponseCode;
827         ServerResponse.ResultMessage = SessionErrorBuffer;
828         return ServerResponse;
829         
832 COServerResponse CardDAV2::EditContact(std::string Location, std::string Data){
834         // Check if authentication was successful, otherwise don't do anything.
836         COServerResponse ServerResponse;
837         
838         if (AuthPassed == false){
839                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
840                 ServerResponse.EntityTag = "";
841                 ServerResponse.SessionCode = 0;
842                 ServerResponse.ResultCode = 0;
843                 ServerResponse.ResultMessage = "";
844                 return ServerResponse;
845         }
847         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
848         ResetResults();
849         
850         string ServerAddressURL = BuildURL(ServerPrefix + Location);
851         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
852         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "PUT");
853         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, Data.c_str());
854         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(Data.c_str()));
855         
856         HeaderList = curl_slist_append(HeaderList, "Content-Type: text/vcard; charset=utf-8");
858         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, HeaderList);
859         
860         if (TestMode == true){
861                 SessionResult = curl_easy_perform(ConnectionSession);
862         } else {
863                 SessionResult = curl_easy_perform(ConnectionSession);
864         }
865         
866         switch(SessionResult){
867                 case CURLE_OK:
868                         SSLStatus = true;
869                         SSLVerified = COSSL_VERIFIED;
870                         break;
871                 case CURLE_SSL_CACERT:
872                 case CURLE_SSL_CONNECT_ERROR:
873                         SSLStatus = true;
874                         SSLVerified = COSSL_UNABLETOVERIFY;
875                         break;
876                 default:
877                         break;
878         };
879         
880         long SessionResponseCode = 0;
881         
882         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
883         
884         if (SessionResponseCode == 200 || SessionResponseCode == 201 || SessionResponseCode == 204){
885                 AuthPassed = true;
886                 ValidResponse = true;
887         } else if (SessionResponseCode == 403){
888                 AuthPassed = false;
889                 ValidResponse = true;
890         } else if (SessionResponseCode >= 400){
891                 AuthPassed = false;
892                 ValidResponse = true;
893         } else {
894                 AuthPassed = false;
895                 ValidResponse = false;                  
896         }
897         
898         if (ValidResponse == false || AuthPassed == false){
899                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
900                 ServerResponse.EntityTag = "";
901                 ServerResponse.SessionCode = SessionResult;
902                 ServerResponse.ResultCode = SessionResponseCode;
903                 ServerResponse.ResultMessage = "";
904                 return ServerResponse;
905         }
906         
907         CanProcess = true;
908         
909         ServerResponse.RequestResult = COREQUEST_OK;
910         ServerResponse.EntityTag = "";
911         ServerResponse.SessionCode = SessionResult;
912         ServerResponse.ResultCode = SessionResponseCode;
913         ServerResponse.ResultMessage = SessionErrorBuffer;
914         return ServerResponse;
915         
918 COServerResponse CardDAV2::DeleteContact(std::string Location, std::string EntityTag){
919         
922 COServerResponse CardDAV2::GetServerEntityTagValue(std::string Location){
923         
924         // Check if authentication was successful, otherwise don't do anything.
926         COServerResponse ServerResponse;
927         
928         if (AuthPassed == false){
929                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
930                 ServerResponse.EntityTag = "";
931                 ServerResponse.SessionCode = 0;
932                 ServerResponse.ResultCode = 0;
933                 ServerResponse.ResultMessage = "";
934                 return ServerResponse;
935         }
937         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
938         ResetResults();
939         
940         static const char* GetETagQuery =
941         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
942         "<C:addressbook-query xmlns:D=\"DAV:\""
943         "       xmlns:C=\"urn:ietf:params:xml:ns:carddav\">"
944         "<D:prop><D:getetag/>"
945         "</D:prop>"
946         "<C:filter/>"
947         "</C:addressbook-query>";
948         
949         string ServerAddressURL = BuildURL(ServerPrefix + Location);
950         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
951         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "REPORT");
952         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, GetETagQuery);
953         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, strlen(GetETagQuery));
954         
955         if (TestMode == true){
956                 SessionResult = curl_easy_perform(ConnectionSession);
957         } else {
958                 SessionResult = curl_easy_perform(ConnectionSession);
959         }
960         
961         switch(SessionResult){
962                 case CURLE_OK:
963                         SSLStatus = true;
964                         SSLVerified = COSSL_VERIFIED;
965                         break;
966                 case CURLE_SSL_CACERT:
967                 case CURLE_SSL_CONNECT_ERROR:
968                         SSLStatus = true;
969                         SSLVerified = COSSL_UNABLETOVERIFY;
970                         break;
971                 default:
972                         break;
973         };
974         
975         long SessionResponseCode = 0;
976         
977         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
978         
979         if (SessionResponseCode == 207){
980                 AuthPassed = true;
981                 ValidResponse = true;
982         } else if (SessionResponseCode == 403){
983                 AuthPassed = false;
984                 ValidResponse = true;
985         } else if (SessionResponseCode >= 400){
986                 AuthPassed = false;
987                 ValidResponse = true;
988         } else {
989                 AuthPassed = false;
990                 ValidResponse = false;                  
991         }
992         
993         if (ValidResponse == false || AuthPassed == false){
994                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
995                 ServerResponse.EntityTag = "";
996                 ServerResponse.SessionCode = SessionResult;
997                 ServerResponse.ResultCode = SessionResponseCode;
998                 ServerResponse.ResultMessage = "";
999                 return ServerResponse;
1000         }
1001         
1002         CanProcess = true;
1003         
1004         ServerResponse.RequestResult = COREQUEST_OK;
1005         ServerResponse.EntityTag = GetETagValue();
1006         ServerResponse.SessionCode = SessionResult;
1007         ServerResponse.ResultCode = SessionResponseCode;
1008         ServerResponse.ResultMessage = SessionErrorBuffer;
1009         
1010         return ServerResponse;
1011         
1014 COServerResponse CardDAV2::GetContact(std::string Location, std::string *ContactData){
1015         
1016         // Check if authentication was successful, otherwise don't do anything.
1018         COServerResponse ServerResponse;
1019         
1020         if (AuthPassed == false){
1021                 ServerResponse.RequestResult = COREQUEST_ERROR_NOTCONNECTED;
1022                 ServerResponse.EntityTag = "";
1023                 ServerResponse.SessionCode = 0;
1024                 ServerResponse.ResultCode = 0;
1025                 ServerResponse.ResultMessage = "";
1026                 return ServerResponse;
1027         }
1029         ServerSSL ? SetupDefaultParametersSSL(true) : SetupDefaultParametersNonSSL(true);
1030         ResetResults();
1031         
1032         string ServerAddressURL = BuildURL(ServerPrefix + Location);
1033         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
1034         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1035         
1036         if (TestMode == true){
1037                 SessionResult = curl_easy_perform(ConnectionSession);
1038         } else {
1039                 SessionResult = curl_easy_perform(ConnectionSession);
1040         }
1041         
1042         switch(SessionResult){
1043                 case CURLE_OK:
1044                         SSLStatus = true;
1045                         SSLVerified = COSSL_VERIFIED;
1046                         break;
1047                 case CURLE_SSL_CACERT:
1048                 case CURLE_SSL_CONNECT_ERROR:
1049                         SSLStatus = true;
1050                         SSLVerified = COSSL_UNABLETOVERIFY;
1051                         break;
1052                 default:
1053                         break;
1054         };
1055         
1056         long SessionResponseCode = 0;
1057         
1058         curl_easy_getinfo(ConnectionSession, CURLINFO_RESPONSE_CODE, &SessionResponseCode);
1059         
1060         if (SessionResponseCode == 200){
1061                 AuthPassed = true;
1062                 ValidResponse = true;
1063         } else if (SessionResponseCode == 403){
1064                 AuthPassed = false;
1065                 ValidResponse = true;
1066         } else if (SessionResponseCode >= 400){
1067                 AuthPassed = false;
1068                 ValidResponse = true;
1069         } else {
1070                 AuthPassed = false;
1071                 ValidResponse = false;                  
1072         }
1073         
1074         if (ValidResponse == false && AuthPassed == false){
1075                 ServerResponse.RequestResult = COREQUEST_ERROR_SERVER;
1076                 ServerResponse.EntityTag = "";
1077                 ServerResponse.SessionCode = SessionResult;
1078                 ServerResponse.ResultCode = SessionResponseCode;
1079                 ServerResponse.ResultMessage = "";
1080                 return ServerResponse;
1081         }
1082         
1083         CanProcess = true;
1084         
1085         ServerResponse.RequestResult = COREQUEST_OK;
1086         ServerResponse.EntityTag = "";
1087         ServerResponse.SessionCode = SessionResult;
1088         ServerResponse.ResultCode = SessionResponseCode;
1089         ServerResponse.ResultMessage = SessionErrorBuffer;
1090         
1091         (*ContactData) = PageData;
1092         
1093         return ServerResponse;
1094         
1097 COContactList CardDAV2::GetContactList(std::string SyncToken){
1098         
1100         
1101 bool CardDAV2::CanDoProcessing(){
1102         return CanProcess;
1105 bool CardDAV2::CanDoSSL(){
1106         return SSLStatus;
1109 COSSLVerified CardDAV2::SSLVerify(){
1110         return SSLVerified;
1113 bool CardDAV2::AbleToLogin(){
1114         return AuthPassed;
1117 bool CardDAV2::HasValidResponse(){
1118         return ValidResponse;
1121 bool CardDAV2::IsSelfSigned(){
1122         return SSLSelfSigned;
1125 void CardDAV2::SetupDefaultParametersNonSSL(bool DoAuthentication){
1126         
1127         std::string ServerAddress = "";
1129         string ServerAddressURL = "http://" + ServerAddress + ":" + to_string(ServerPort) + "/";
1130         string UsernamePassword = ServerUser + ":" + ServerPass;
1131         
1132         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddress.c_str());
1133         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
1134         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1135         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
1136         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
1137         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
1138         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
1139         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
1140         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
1141         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
1142         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1143         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
1144         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
1145         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
1146         
1147         if (DoAuthentication == true){
1148                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
1149         } else {
1150                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
1151         }
1152         
1155 void CardDAV2::SetupDefaultParametersSSL(bool DoAuthentication){
1156         
1157         // Setup the default parameters.
1158         
1159         string ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + "/";
1160         string UsernamePassword = ServerUser + ":" + ServerPass;
1161         
1162         curl_easy_setopt(ConnectionSession, CURLOPT_URL, ServerAddressURL.c_str());
1163         curl_easy_setopt(ConnectionSession, CURLOPT_NOPROGRESS, 1L);
1164         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1165         curl_easy_setopt(ConnectionSession, CURLOPT_TIMEOUT, 60);
1166         curl_easy_setopt(ConnectionSession, CURLOPT_FAILONERROR, true);
1167         curl_easy_setopt(ConnectionSession, CURLOPT_USERAGENT, XSDAB_USERAGENT);
1168         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEFUNCTION, CardDAV2::WritebackFunc);
1169         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEDATA, &PageData);
1170         curl_easy_setopt(ConnectionSession, CURLOPT_WRITEHEADER, &PageHeader);
1171         curl_easy_setopt(ConnectionSession, CURLOPT_ERRORBUFFER, SessionErrorBuffer);
1172         curl_easy_setopt(ConnectionSession, CURLOPT_NOSIGNAL, 1);
1173         curl_easy_setopt(ConnectionSession, CURLOPT_CERTINFO, 1);
1174         curl_easy_setopt(ConnectionSession, CURLOPT_VERBOSE, 1);
1175         curl_easy_setopt(ConnectionSession, CURLOPT_CUSTOMREQUEST, "GET");
1176         curl_easy_setopt(ConnectionSession, CURLOPT_HTTPHEADER, nullptr);
1177         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDS, nullptr);
1178         curl_easy_setopt(ConnectionSession, CURLOPT_POSTFIELDSIZE, 0L);
1179         
1180         if (DoAuthentication == true){
1181                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, UsernamePassword.c_str());
1182         } else {
1183                 curl_easy_setopt(ConnectionSession, CURLOPT_USERPWD, ":");              
1184         }
1185         
1186         if (EnableSSLBypass == true){
1187                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 0);
1188                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 0);
1189         } else {
1190                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYHOST, 2);
1191                 curl_easy_setopt(ConnectionSession, CURLOPT_SSL_VERIFYPEER, 1);         
1192         }
1193         
1194         if (TestMode == false && ServerAccount.size() > 0){
1195                 
1196                 // Check if the server certificate file exists.
1197                 
1198                 string CertificateFilename = GetAccountDir(ServerAccount, true);
1199                 
1200                 if (wxFile::Exists(CertificateFilename)){
1201                         
1202                         curl_easy_setopt(ConnectionSession, CURLOPT_CAINFO, CertificateFilename.c_str());
1203                         
1204                 }
1205                 
1206         }
1207         
1210 string CardDAV2::BuildURL(string URI){
1211         
1212         string ServerAddressURL;
1213         
1214         if (SSLStatus == true){
1215                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;      
1216         } else {
1217                 ServerAddressURL = "https://" + ServerAddress + ":" + to_string(ServerPort) + URI;
1218         }
1219         
1220         return ServerAddressURL;
1221         
1224 string CardDAV2::GetErrorMessage(){
1225         
1226         ErrorMessage = SessionErrorBuffer;      
1227         return ErrorMessage;
1228         
1231 void CardDAV2::ResetResults(){
1232         
1233         SSLStatus = false;
1234         COSSLVerified SSLVerified = COSSL_NORESULT;
1235         ValidResponse = false;
1236         AuthPassed = false;
1237         CanProcess = false;
1238         SSLSelfSigned = false;
1239         TaskCompleted = false;
1240         ErrorMessage = "";
1241         SessionErrorBuffer[0] = '\0';
1242         PageData = "";
1243         PageHeader = "";
1244         if (HeaderList != nullptr){
1245                 curl_slist_free_all(HeaderList);
1246                 HeaderList = nullptr;
1247         }
1248         
1251 string CardDAV2::GetETagValue(){
1252         
1253         xmlDocPtr xmlCardDAVDoc;
1255         xmlCardDAVDoc = xmlReadMemory(PageData.c_str(), (int)PageData.size(), "noname.xml", NULL, 0);
1257         xmlNodePtr nodeLevel1;
1258         xmlNodePtr nodeLevel2;
1259         xmlNodePtr nodeLevel3;
1260         xmlNodePtr nodeLevel4;
1261         xmlNodePtr nodeLevel5;
1262         xmlNodePtr nodeLevel6;
1264         //std::map<wxString,wxString> xmlDataMap;
1266         std::string DataFilename;
1267         std::string ETagData;
1269         std::string xmlStringSafe;
1270         std::string ETagValue;
1272         // Tranverse through the catacombs of the response to get our ETag for the file.
1274         for (nodeLevel1 = xmlCardDAVDoc->children;
1275                 nodeLevel1 != NULL;
1276                 nodeLevel1 = nodeLevel1->next)
1277         {
1279                 bool HREFFound = FALSE;
1280                 bool ETagFound = FALSE;
1282                 for (nodeLevel2 = nodeLevel1->children;
1283                         nodeLevel2 != NULL;
1284                         nodeLevel2 = nodeLevel2->next)
1285                 {
1287                         for (nodeLevel3 = nodeLevel2->children;
1288                         nodeLevel3 != NULL;
1289                         nodeLevel3 = nodeLevel3->next)
1290                         {
1292                                 if (!xmlStrcmp(nodeLevel3->name, (const xmlChar *)"href") ||
1293                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"d:href") ||
1294                                 !xmlStrcmp(nodeLevel3->name, (const xmlChar *)"D:href")
1295                                 ){
1297                                         // Get the filename.
1298                                         
1299                                         for (nodeLevel4 = nodeLevel3->children;
1300                                         nodeLevel4 != NULL;
1301                                         nodeLevel4 = nodeLevel4->next)
1302                                         {
1303                                         
1304                                                 if (!xmlStrcmp(nodeLevel4->name, (const xmlChar *)"text") ||
1305                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"d:text") ||
1306                                                 !xmlStrcmp(nodeLevel4->name, (const xmlChar *)"D:text")
1307                                                 ){
1309                                                         DataFilename = wxString::FromUTF8((const char*)nodeLevel4->content);
1310                                                         wxStringTokenizer wSTDFilename(DataFilename, wxT("/"));
1311                                                 
1312                                                         while (wSTDFilename.HasMoreTokens()){
1313                                                         
1314                                                                 DataFilename = wSTDFilename.GetNextToken().ToStdString();
1315                                                         
1316                                                         }
1317                                                         
1318                                                         HREFFound = TRUE;
1319                                                 
1320                                                 }
1321                                                 
1322         
1323                                         
1324                                         }
1326                                 } else {
1328                                         for (nodeLevel4 = nodeLevel3->children;
1329                                         nodeLevel4 != NULL;
1330                                         nodeLevel4 = nodeLevel4->next)
1331                                         {
1332                                                         
1333                                                         for (nodeLevel5 = nodeLevel4->children;
1334                                                         nodeLevel5 != NULL;
1335                                                         nodeLevel5 = nodeLevel5->next)
1336                                                         {
1338                                                                 if (!xmlStrcmp(nodeLevel5->name, (const xmlChar *)"getetag") ||
1339                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"d:getetag") ||
1340                                                                 !xmlStrcmp(nodeLevel5->name, (const xmlChar *)"D:getetag")
1341                                                                 ){
1343                                                                         for (nodeLevel6 = nodeLevel5->children;
1344                                                                         nodeLevel6 != NULL;
1345                                                                         nodeLevel6 = nodeLevel6->next)
1346                                                                         {
1347                                                         
1348                                                                                 // Strip the quotes from the ETag.
1349                                                         
1350                                                                                 ETagData = (const char*)nodeLevel6->content;
1351                                                                                 if (ETagData[0] == '"' && ETagData[(ETagData.size() - 1)] == '"'){
1352                                                         
1353                                                                                         ETagData.erase(0, 1);
1354                                                                                         ETagData.erase((ETagData.size() - 1));
1355                                                         
1356                                                                                 }
1357                                                                         
1358                                                                                 ETagFound = TRUE;
1360                                                                         }
1361                                                                         
1362                                                                 }
1364                                                         }       
1366                                         }
1368                                 }
1370                         }
1372                 }
1373                 
1374                 if (HREFFound == TRUE && ETagFound == TRUE){
1375                                 
1376                         // Add to the map data.
1377                                 
1378                         ETagValue = ETagData;
1379                         
1380                         HREFFound = FALSE;
1381                         ETagFound = FALSE;
1382                         break;
1383                                 
1384                 }
1387         }
1389         xmlFreeDoc(xmlCardDAVDoc);
1390         
1391         return ETagValue;
1392         
1395 string CardDAV2::GetETagHeader(){
1396         
1397         // Go through each of the lines looking for the
1398         // 'DAV:' section.
1399         
1400         string HeaderName;
1401         string HeaderValue;
1402         bool FastForward = false;
1403         
1404         for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
1405                 
1406                 if (FastForward == true){
1407                         
1408                         if (PageHeader[HeaderSeek] == '\n'){
1409                                 FastForward = false;
1410                         }
1411                         
1412                         continue;
1413                         
1414                 }
1415                 
1416                 try {
1417                         PageHeader.substr(HeaderSeek, 5) == "ETag:";
1418                 }
1419                 
1420                 catch (const out_of_range &oor){
1421                         break;
1422                 }
1423                 
1424                 if (PageHeader.substr(HeaderSeek, 5) == "ETag:"){
1425                         
1426                         int CharacterSeek = 5;
1427                         
1428                         while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
1429                                 
1430                                 if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
1431                                         break;
1432                                 }
1433                                 
1434                                 HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
1435                                 CharacterSeek++;
1436                         }
1437                         
1438                         break;
1439                         
1440                 } else {
1441                         
1442                         FastForward = true;
1443                         continue;
1444                         
1445                 }
1446                 
1447                 if (PageHeader[HeaderSeek] == '\n'){
1448                         HeaderName = "";
1449                 }
1450                 
1451                 //HeaderName += PageHeader.substr(HeaderSeek, 1);
1452                 
1453         }
1454         
1455         // Check for quotation marks at the start and end and strip
1456         // them out.
1457         
1458         if (HeaderValue.size() >= 2){
1459                 
1460                 if (HeaderValue[0] == '"'){
1461                         HeaderValue.erase((HeaderValue.size() - 1));
1462                         HeaderValue.erase(0);
1463                 }
1464                 
1465         }
1466         
1467         return HeaderValue;
1468         
1471 vector<string> CardDAV2::GetDAVHeader(){
1472         
1473         // Go through each of the lines looking for the
1474         // 'DAV:' section.
1475         
1476         string HeaderName;
1477         string HeaderValue;
1478         bool FastForward = false;
1479         vector<string> DAVHeaderList;
1480         
1481         for (int HeaderSeek = 0; HeaderSeek < PageHeader.size(); HeaderSeek++){
1482                 
1483                 if (FastForward == true){
1484                         
1485                         if (PageHeader[HeaderSeek] == '\n'){
1486                                 FastForward = false;
1487                         }
1488                         
1489                         continue;
1490                         
1491                 }
1492                 
1493                 try {
1494                         PageHeader.substr(HeaderSeek, 4) == "DAV:";
1495                 }
1496                 
1497                 catch (const out_of_range &oor){
1498                         break;
1499                 }
1500                 
1501                 if (PageHeader.substr(HeaderSeek, 4) == "DAV:"){
1502                         
1503                         int CharacterSeek = 5;
1504                         
1505                         while ((HeaderSeek + CharacterSeek) < PageHeader.size()){
1506                                 
1507                                 if (PageHeader.substr((HeaderSeek + CharacterSeek), 2) == "\r\n"){
1508                                         break;
1509                                 }
1510                                 
1511                                 HeaderValue += PageHeader.substr((HeaderSeek + CharacterSeek), 1);
1512                                 CharacterSeek++;
1513                         }
1514                         
1515                         break;
1516                         
1517                 } else {
1518                         
1519                         FastForward = true;
1520                         continue;
1521                         
1522                 }
1523                 
1524                 if (PageHeader[HeaderSeek] == '\n'){
1525                         HeaderName = "";
1526                 }
1527                 
1528                 //HeaderName += PageHeader.substr(HeaderSeek, 1);
1529                 
1530         }
1531         
1532         // Split the header data.
1533         
1534         std::string DAVHeaderValue;
1535         
1536         for (int HeaderSeek = 0; HeaderSeek < HeaderValue.size(); HeaderSeek++){
1537                 
1538                 if (HeaderValue.substr(HeaderSeek, 1) == ","){
1539                         DAVHeaderList.push_back(DAVHeaderValue);
1540                         DAVHeaderValue = "";
1541                         HeaderSeek++;
1542                         continue;
1543                 }
1544                 
1545                 DAVHeaderValue += HeaderValue[HeaderSeek];
1546                 
1547         }
1548         
1549         if (DAVHeaderValue.size() > 0){
1550                 
1551                 DAVHeaderList.push_back(DAVHeaderValue);
1552                 
1553         }
1554         
1555         return DAVHeaderList;
1556         
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