1 // CalDAV.cpp - CalDAV Connection Object.
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar 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.
11 // Xestia Calendar 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.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
23 size_t CalDAVReceive(char *receivedBuffer, size_t size, size_t newMemoryBytes, string *stringPointer)
26 stringPointer->append(receivedBuffer, newMemoryBytes);
28 return size * newMemoryBytes;
32 size_t CalDAVSend(char *sendBuffer, size_t size, size_t newMemoryBytes, void *dataStruct){
34 struct CalDAVSendData *uploadPtr = (struct CalDAVSendData *)dataStruct;
36 if (uploadPtr->sizeleft){
38 uploadPtr->sizeleft--;
41 charSend = (*uploadPtr->readptr)[uploadPtr->seek];
43 *sendBuffer = charSend;
57 // Setup the objects within the CalDAV connection
60 connectionHandle = curl_easy_init();
66 // Destory the objects within the CalDAV connection
69 curl_easy_cleanup(connectionHandle);
70 connectionHandle = nullptr;
74 void CalDAV::SetupConnectionData(CalDAVConnectionData *connData){
76 // Check if ConnData is a nullptr, return if it is.
78 if (connData == nullptr){
82 // Set the connection settings to the values from ConnData.
84 connectionData = (*connData);
88 CalDAVStatus CalDAV::GetConnectionData(){
90 // Get the current connection settings for the CalDAV
91 // connection object and return a CalDAVStatus object.
93 CalDAVStatus connectionStatus;
95 connectionStatus.hostname = connectionData.hostname;
96 connectionStatus.port = connectionData.port;
97 connectionStatus.username = connectionData.username;
98 connectionStatus.prefix = connectionData.prefix;
99 connectionStatus.useSSL = connectionData.useSSL;
100 connectionStatus.timeout = connectionData.timeout;
102 return connectionStatus;
106 CalDAVServerResult CalDAV::Connect(){
108 CalDAVServerResult serverResult;
110 string serverAddress = "";
111 string serverUserPass = "";
113 // Setup the server address.
115 serverAddress = BuildServerAddress(&connectionData, "/principals/");
117 // Setup the server password.
119 serverUserPass += connectionData.username;
120 serverUserPass += ":";
121 serverUserPass += connectionData.password;
123 curl_easy_setopt(connectionHandle, CURLOPT_URL, serverAddress.c_str());
124 curl_easy_setopt(connectionHandle, CURLOPT_USERPWD, serverUserPass.c_str());
125 curl_easy_setopt(connectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
126 curl_easy_setopt(connectionHandle, CURLOPT_FAILONERROR, 1L);
127 curl_easy_setopt(connectionHandle, CURLOPT_TIMEOUT, connectionData.timeout);
128 curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive);
129 curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &serverData);
130 curl_easy_setopt(connectionHandle, CURLOPT_WRITEHEADER, &serverHeader);
132 // Connect to the CalDAV server.
134 serverResult.code = curl_easy_perform(connectionHandle);
136 // Process the result received from the server.
138 if (serverResult.code != CURLE_OK){
140 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
144 serverResult.result = CALDAVQUERYRESULT_OK;
148 // Get the HTTP code.
150 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
156 CalDAVServerResult CalDAV::GetServerResult(){
158 return connectionServerResult;
162 CalDAVServerSupport CalDAV::GetServerSupport(){
164 CalDAVServerSupport serverStatus;
166 // Setup the server connection.
168 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
170 CURLcode serverResult = curl_easy_perform(connectionHandle);
174 if (serverResult == CURLE_OK){
175 connectionServerResult.result = CALDAVQUERYRESULT_OK;
177 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
179 connectionServerResult.code = serverResult;
180 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
182 if (serverResult != CURLE_OK){
186 // Check that the server header has data in,
187 // otherwise return an "empty" CalDAVServerSupport.
189 if (serverHeader.size() == 0){
193 // Process each line looking for the first DAV header
196 bool newlineMode = true;
200 for (int charSeek = 0; charSeek < serverHeader.size(); charSeek++){
202 if (newlineMode == true){
204 // Check if we have reached the end of the string.
206 if (charSeek >= serverHeader.size()){
212 // Check the first four letters to make sure
215 string davHeaderCheck = "";
218 davHeaderCheck = serverHeader.substr(charSeek, 4);
221 catch (out_of_range &oor){
225 if (davHeaderCheck == "DAV:"){
229 for (; charSeek < serverHeader.size(); charSeek++){
231 if (serverHeader[charSeek] == '\n'){
237 davLine.push_back(serverHeader[charSeek]);
249 if (serverHeader[charSeek] == '\n'){
257 // Process the DAV line.
259 vector<string> davLineData;
260 string davSegmentString;
262 for (int charSeek = 0; charSeek < davLine.size(); charSeek++){
264 if (davLine[charSeek] == ' '){
268 if (davLine[charSeek] == ','){
270 davLineData.push_back(davSegmentString);
271 davSegmentString.clear();
276 davSegmentString += davLine[charSeek];
280 // Process the DAV values and set each value
281 // to true as required.
283 for (int davItemSeek = 0;
284 davItemSeek < davLineData.size();
287 if (davLineData.at(davItemSeek) == "calendar-access"){
289 serverStatus.basicSupport = true;
295 // Reset the connection status.
297 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
303 string CalDAV::GetUserPrincipal(){
305 string currentUserPrincipal = "";
306 string userPrincipalRequest = "";
307 CalDAVSendData userPrincipalSendData;
309 userPrincipalRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
310 "<d:propfind xmlns:d=\"DAV:\">\n"
312 " <d:current-user-principal />\n"
316 userPrincipalSendData.readptr = &userPrincipalRequest;
317 userPrincipalSendData.sizeleft = userPrincipalRequest.size();
321 struct curl_slist *userPrincipalRequestHeader = NULL;
323 userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Depth: 0");
324 userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Prefer: return-minimal");
325 userPrincipalRequestHeader = curl_slist_append(userPrincipalRequestHeader, "Content-Type: application/xml; charset=utf-8");
327 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, userPrincipalRequestHeader);
329 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
330 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
331 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &userPrincipalSendData);
332 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
337 serverHeader.clear();
339 CURLcode serverResult = curl_easy_perform(connectionHandle);
343 if (serverResult == CURLE_OK){
344 connectionServerResult.result = CALDAVQUERYRESULT_OK;
346 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
348 connectionServerResult.code = serverResult;
349 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
351 if (serverResult != CURLE_OK){
353 return currentUserPrincipal;
357 // Process the User Principal from the ServerData.
359 currentUserPrincipal = ProcessXMLUserPrincipal();
361 // Reset the changed settings.
363 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
364 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
365 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
367 return currentUserPrincipal;
371 string CalDAV::GetCalendarHome(string userPrincipalURI){
373 string calendarHomeURI = "";
375 // Build the Calendar Home URL address.
377 string calendarHomeURL = BuildServerAddress(&connectionData, userPrincipalURI);
379 // Setup the header request.
381 CalDAVSendData calendarHomeSendData;
383 string calendarHomeRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
384 "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
386 " <c:calendar-home-set />\n"
390 calendarHomeSendData.readptr = &calendarHomeRequest;
391 calendarHomeSendData.sizeleft = calendarHomeRequest.size();
395 struct curl_slist *calendarRequestHeader = NULL;
397 calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Depth: 0");
398 calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Prefer: return-minimal");
399 calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: application/xml; charset=utf-8");
401 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
402 curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarHomeURL.c_str());
403 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
404 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
405 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarHomeSendData);
406 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
411 serverHeader.clear();
413 CURLcode serverResult = curl_easy_perform(connectionHandle);
417 if (serverResult == CURLE_OK){
418 connectionServerResult.result = CALDAVQUERYRESULT_OK;
420 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
422 connectionServerResult.code = serverResult;
423 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
425 if (serverResult != CURLE_OK){
427 return calendarHomeURI;
431 // Process the User Principal from the ServerData.
433 calendarHomeURI = ProcessXMLCalendarHome();
435 // Reset the changed settings.
437 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
438 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
440 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
441 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
442 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
443 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
445 return calendarHomeURI;
449 CalDAVCalendarList CalDAV::GetCalendars(){
451 CalDAVCalendarList serverList;
452 CalDAVSendData calendarListSendData;
454 // Build the server address.
456 string userPrincipalURI = "";
457 userPrincipalURI = GetUserPrincipal();
459 if (userPrincipalURI.size() == 0){
465 string calendarHomeURI = "";
466 calendarHomeURI = GetCalendarHome(userPrincipalURI);
468 string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURI);
470 string calendarListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
471 "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
472 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
474 " <d:resourcetype />\n"
475 " <d:displayname />\n"
476 " <d:sync-token />\n"
477 " <x0:calendar-color />\n"
478 " <x0:calendar-order />\n"
480 " <c:supported-calendar-component-set />\n"
481 " <c:calendar-description />\n"
485 calendarListSendData.readptr = &calendarListRequest;
486 calendarListSendData.sizeleft = calendarListRequest.size();
490 struct curl_slist *calendarListRequestHeader = NULL;
492 calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Depth: 1");
493 calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Prefer: return-minimal");
494 calendarListRequestHeader = curl_slist_append(calendarListRequestHeader, "Content-Type: application/xml; charset=utf-8");
496 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarListRequestHeader);
497 curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
498 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPFIND");
499 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
500 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarListSendData);
501 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
506 serverHeader.clear();
508 CURLcode serverResult = curl_easy_perform(connectionHandle);
510 //ServerList = ProcessXMLCalendarList();
512 if (serverResult == CURLE_OK){
513 connectionServerResult.result = CALDAVQUERYRESULT_OK;
515 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
517 connectionServerResult.code = serverResult;
518 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
520 if (serverResult != CURLE_OK){
526 // Process the received XML data into a list of calendars
529 serverList = ProcessXMLCalendarList();
531 // Restore the original settings.
533 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
535 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
536 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
537 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
538 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
539 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
545 CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF){
547 CalDAVEntryList entryList;
548 CalDAVSendData entryListSendData;
550 if (calendarHREF->size() == 0){
556 string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
558 string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
560 /*if (CalendarTag == nullptr){*/
562 entryListRequest += "<c:calendar-query xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
563 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
566 " <c:calendar-data />\n"
569 " <c:comp-filter name=\"VCALENDAR\" />\n"
571 "</c:calendar-query>";
575 EntryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
576 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
578 EntryListRequest += *CalendarTag;
579 EntryListRequest += "</d:sync-token>\n"
580 " <d:sync-level>1</d:sync-level>\n"
583 " <c:calendar-data />\n"
585 "</d:sync-collection>";
589 entryListSendData.readptr = &entryListRequest;
590 entryListSendData.sizeleft = entryListRequest.size();
592 struct curl_slist *entryListRequestHeader = NULL;
594 entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
596 /*if (CalendarTag != nullptr){
598 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
599 EntryListRequestHeader = curl_slist_append(EntryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
603 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
604 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
605 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
606 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
607 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
608 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
613 serverHeader.clear();
615 CURLcode serverResult = curl_easy_perform(connectionHandle);
617 //ServerList = ProcessXMLCalendarList();
619 if (serverResult == CURLE_OK){
620 connectionServerResult.result = CALDAVQUERYRESULT_OK;
622 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
624 connectionServerResult.code = serverResult;
625 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
627 if (serverResult != CURLE_OK){
633 // Process the received XML data into a list of calendars
636 entryList = ProcessXMLEntryList();
638 // Restore the original settings.
640 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
642 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
643 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
644 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
645 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
646 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
652 CalDAVEntryList CalDAV::GetEntryList(string *calendarHREF, string *calendarTag){
654 CalDAVEntryList entryList;
655 CalDAVSendData entryListSendData;
657 if (calendarHREF->size() == 0){
663 string entryListURLAddress = BuildServerAddress(&connectionData, *calendarHREF);
665 // First query: Get the list of contacts that need to be updated.
667 string entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
669 entryListRequest += "<d:sync-collection xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\""
670 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:x0=\"http://apple.com/ns/ical/\">\n"
673 if (calendarTag != nullptr){
675 entryListRequest += *calendarTag;
679 entryListRequest += "";
683 entryListRequest += "</d:sync-token>\n"
684 " <d:sync-level>1</d:sync-level>\n"
688 "</d:sync-collection>";
690 entryListSendData.readptr = &entryListRequest;
691 entryListSendData.sizeleft = entryListRequest.size();
693 struct curl_slist *entryListRequestHeader = NULL;
695 entryListRequestHeader = curl_slist_append(entryListRequestHeader, "Content-Type: application/xml; charset=utf-8");
697 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
698 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
699 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
700 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
701 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryListSendData);
702 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
707 serverHeader.clear();
709 CURLcode serverResult = curl_easy_perform(connectionHandle);
711 if (serverResult == CURLE_OK){
712 connectionServerResult.result = CALDAVQUERYRESULT_OK;
714 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
716 connectionServerResult.code = serverResult;
717 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
719 if (serverResult != CURLE_OK){
725 entryList = ProcessXMLSyncTokenList();
727 // Check the last entry matches the HREF and if it
728 // does then delete it.
730 if (entryList.href.size() > 0) {
732 if (entryList.href.rbegin()->second == *calendarHREF){
734 entryList.href.erase((entryList.href.size() - 1));
735 entryList.tag.erase((entryList.href.size() - 1));
736 entryList.data.erase((entryList.href.size() - 1));
742 // Build the list into a new list for getting the new
743 // calendar data with.
745 entryListRequest.clear();
747 entryListRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
749 entryListRequest += "<c:calendar-multiget xmlns:d=\"DAV:\" "
750 " xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
753 " <c:calendar-data />\n"
756 for (std::map<int,string>::iterator hrefIter = entryList.href.begin();
757 hrefIter != entryList.href.end(); hrefIter++){
759 string entryListHREFString = hrefIter->second;
761 entryListRequest += " <d:href>";
762 entryListRequest += entryListHREFString;
763 entryListRequest += "</d:href>\n";
767 entryListRequest += "</c:calendar-multiget>";
769 CalDAVSendData updatedEntryListSendData;
771 updatedEntryListSendData.readptr = &entryListRequest;
772 updatedEntryListSendData.sizeleft = entryListRequest.size();
774 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, entryListRequestHeader);
775 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryListURLAddress.c_str());
776 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
777 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
778 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &updatedEntryListSendData);
779 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
781 // Get the updated calendar data.
784 serverHeader.clear();
785 entryList.href.clear();
786 entryList.tag.clear();
787 entryList.data.clear();
789 serverResult = curl_easy_perform(connectionHandle);
791 // Check the last entry matches the HREF and if it
792 // does then delete it.
794 if (serverResult == CURLE_OK){
795 connectionServerResult.result = CALDAVQUERYRESULT_OK;
797 connectionServerResult.result = CALDAVQUERYRESULT_SERVERERROR;
799 connectionServerResult.code = serverResult;
800 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &connectionServerResult.httpCode);
802 if (serverResult != CURLE_OK){
808 entryList = ProcessXMLEntryList();
810 // Second query: Get the list of contact data for the contacts that have
813 // Restore the original settings.
815 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
817 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
818 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
819 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
820 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
821 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
827 CalDAVServerResult CalDAV::AddCalendar(string calendarName){
829 CalDAVServerResult serverResult;
831 AddCalendar(&calendarName, nullptr);
837 CalDAVServerResult CalDAV::AddCalendar(string *calendarName, string *calendarShortName){
839 CalDAVServerResult serverResult;
840 CalDAVSendData calendarAddSendData;
842 // Build the server address.
844 string userPrincipalURI = "";
845 userPrincipalURI = GetUserPrincipal();
847 if (userPrincipalURI.size() == 0){
853 string calendarHomeURI = "";
854 calendarHomeURI = GetCalendarHome(userPrincipalURI);
856 // Generate the UUID.
858 string UUIDValue = "";
860 if (calendarShortName == nullptr){
862 UUIDValue = GenerateUUID();
863 UUIDValue.erase(UUIDValue.end()-1);
867 UUIDValue = *calendarShortName;
871 string calendarHomeURL = calendarHomeURI;
872 calendarHomeURL.append(UUIDValue);
873 calendarHomeURL.append("/");
875 // Build the calendar list address.
877 string calendarListURLAddress = BuildServerAddress(&connectionData, calendarHomeURL);
879 string calendarAddRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
880 "<c:mkcalendar xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
884 calendarAddRequest += *calendarName;
885 calendarAddRequest += "</d:displayname>\n"
886 " <c:supported-calendar-component-set>\n"
887 " <c:comp name=\"VTODO\"/>\n"
888 " <c:comp name=\"VEVENT\"/>\n"
889 " </c:supported-calendar-component-set>\n"
894 calendarAddSendData.readptr = &calendarAddRequest;
895 calendarAddSendData.sizeleft = calendarAddRequest.size();
899 struct curl_slist *calendarRequestHeader = NULL;
901 //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
902 curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarListURLAddress.c_str());
903 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "MKCALENDAR");
904 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
905 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarAddSendData);
906 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
911 serverHeader.clear();
913 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
915 if (serverConnectionResult == CURLE_OK){
916 serverResult.result = CALDAVQUERYRESULT_OK;
918 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
920 serverResult.code = serverConnectionResult;
921 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
923 // Restore the original settings.
925 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
926 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
927 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
928 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
929 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
930 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
936 CalDAVServerResult CalDAV::EditCalendarProcess(string *calendarHREF,
937 string *calendarName,
938 Colour *calendarColour,
939 string *calendarDescription,
942 CalDAVServerResult serverResult;
943 CalDAVSendData calendarEditSendData;
945 // Build the server address.
947 string userPrincipalURI = "";
948 userPrincipalURI = GetUserPrincipal();
950 if (userPrincipalURI.size() == 0){
956 string calendarHomeURI = "";
957 calendarHomeURI = GetCalendarHome(userPrincipalURI);
959 // Generate the UUID.
961 string UUIDValue = GenerateUUID();
962 UUIDValue.erase(UUIDValue.end()-1);
964 string calendarHomeURL = calendarHomeURI;
965 calendarHomeURL.append(UUIDValue);
966 calendarHomeURL.append("/");
968 // Build the calendar list address.
970 string calendarEditURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
972 string calendarEditRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
973 "<d:propertyupdate xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"\n"
974 " xmlns:x0=\"http://apple.com/ns/ical/\">\n"
978 // Update the calendar name.
980 if (calendarName != nullptr){
982 calendarEditRequest += "<d:displayname>";
983 calendarEditRequest += (*calendarName);
984 calendarEditRequest += "</d:displayname>\n";
988 // Update the calendar colour.
990 if (calendarColour != nullptr){
992 calendarEditRequest += "<x0:calendar-color>";
993 calendarEditRequest += (*calendarColour);
994 calendarEditRequest += "</x0:calendar-color>\n";
998 // Update the calendar description.
1000 if (calendarDescription != nullptr){
1002 calendarEditRequest += "<c:calendar-description>";
1003 calendarEditRequest += (*calendarDescription);
1004 calendarEditRequest += "</c:calendar-description>\n";
1008 // Update the calendar order.
1010 if (calendarOrder != nullptr){
1012 calendarEditRequest += "<x0:calendar-order>";
1013 calendarEditRequest += to_string((*calendarOrder));
1014 calendarEditRequest += "</x0:calendar-order>\n";
1018 calendarEditRequest += " </d:prop>\n"
1020 "</d:propertyupdate>";
1022 calendarEditSendData.readptr = &calendarEditRequest;
1023 calendarEditSendData.sizeleft = calendarEditRequest.size();
1025 // Setup the header.
1027 struct curl_slist *calendarRequestHeader = NULL;
1029 //curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPHEADER, CalendarRequestHeader);
1030 curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarEditURLAddress.c_str());
1031 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
1032 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1033 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &calendarEditSendData);
1034 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1036 // Process the data.
1039 serverHeader.clear();
1041 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1043 if (serverConnectionResult == CURLE_OK){
1044 serverResult.result = CALDAVQUERYRESULT_OK;
1046 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1048 serverResult.code = serverConnectionResult;
1049 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1051 // Restore the original settings.
1053 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1054 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1055 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1056 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1057 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1058 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1060 return serverResult;
1064 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1065 string *calendarName,
1066 Colour *calendarColour,
1067 string *calendarDescription,
1068 int *calendarOrder){
1070 CalDAVServerResult serverResult;
1072 serverResult = EditCalendarProcess(calendarHREF,
1075 calendarDescription,
1078 return serverResult;
1082 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1083 Colour *calendarColour){
1085 CalDAVServerResult serverResult;
1087 serverResult = EditCalendarProcess(calendarHREF,
1093 return serverResult;
1097 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1098 string *calendarName){
1100 CalDAVServerResult serverResult;
1102 serverResult = EditCalendarProcess(calendarHREF,
1108 return serverResult;
1112 CalDAVServerResult CalDAV::EditCalendar(string *calendarHREF,
1113 int *calendarOrder){
1115 CalDAVServerResult serverResult;
1117 serverResult = EditCalendarProcess(calendarHREF,
1123 return serverResult;
1127 CalDAVServerResult CalDAV::EditCalendarDescription(string *calendarHREF,
1128 string *calendarDescription){
1130 CalDAVServerResult serverResult;
1132 serverResult = EditCalendarProcess(calendarHREF,
1135 calendarDescription,
1138 return serverResult;
1142 CalDAVServerResult CalDAV::DeleteCalendar(string *calendarHREF){
1144 CalDAVServerResult serverResult;
1146 // Build the server address.
1148 string userPrincipalURI = "";
1149 userPrincipalURI = GetUserPrincipal();
1151 if (userPrincipalURI.size() == 0){
1153 return serverResult;
1157 string calendarHomeURI = "";
1158 calendarHomeURI = GetCalendarHome(userPrincipalURI);
1160 // Generate the UUID.
1162 string UUIDValue = GenerateUUID();
1163 UUIDValue.erase(UUIDValue.end()-1);
1165 string calendarHomeURL = calendarHomeURI;
1166 calendarHomeURL.append(UUIDValue);
1167 calendarHomeURL.append("/");
1169 // Build the calendar list address.
1171 struct curl_slist *deleteRequestHeader = NULL;
1173 deleteRequestHeader = curl_slist_append(deleteRequestHeader, "Depth: infinity");
1175 string calendarDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarHREF));
1177 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, deleteRequestHeader);
1178 curl_easy_setopt(connectionHandle, CURLOPT_URL, calendarDeleteURLAddress.c_str());
1179 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1181 // Delete the calendar.
1184 serverHeader.clear();
1186 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1188 if (serverConnectionResult == CURLE_OK){
1189 serverResult.result = CALDAVQUERYRESULT_OK;
1191 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1193 serverResult.code = serverConnectionResult;
1194 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1196 // Restore the original settings.
1198 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1199 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1200 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1201 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1202 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1203 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1204 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1206 return serverResult;
1210 CalDAVServerResult CalDAV::GetEntryETag(string *calendarEntryHREF, string *eTagValue){
1212 CalDAVServerResult serverResult;
1213 CalDAVSendData entryETagGetData;
1215 // Build the server address.
1217 string userPrincipalURI = "";
1218 userPrincipalURI = GetUserPrincipal();
1220 if (userPrincipalURI.size() == 0){
1222 return serverResult;
1226 string calendarHomeURI = "";
1227 calendarHomeURI = GetCalendarHome(userPrincipalURI);
1229 // Split the path and filename.
1231 string entryURIPath;
1232 string entryFilename;
1234 SplitPathFilename(calendarEntryHREF, &entryURIPath, &entryFilename);
1236 // Build the request for the server.
1238 string entryETagRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1239 "<c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n"
1244 entryETagRequest += (*calendarEntryHREF);
1245 entryETagRequest += "</d:href>\n"
1246 "</c:calendar-multiget>";
1248 entryETagGetData.readptr = &entryETagRequest;
1249 entryETagGetData.sizeleft = entryETagRequest.size();
1251 // Build the calendar list address.
1253 struct curl_slist *getETagRequestHeader = NULL;
1255 getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Depth: 1");
1256 getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Prefer: return-minimal");
1257 getETagRequestHeader = curl_slist_append(getETagRequestHeader, "Content-Type: application/xml; charset=utf-8");
1259 string getETagURLAddress = BuildServerAddress(&connectionData, entryURIPath);
1261 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, getETagRequestHeader);
1262 curl_easy_setopt(connectionHandle, CURLOPT_URL, getETagURLAddress.c_str());
1263 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "REPORT");
1264 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1265 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryETagGetData);
1266 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1268 // Attempt to get the entity tag.
1271 serverHeader.clear();
1273 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1275 if (serverConnectionResult == CURLE_OK){
1276 serverResult.result = CALDAVQUERYRESULT_OK;
1278 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1280 serverResult.code = serverConnectionResult;
1281 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1283 if (serverConnectionResult != CURLE_OK){
1284 return serverResult;
1287 // Get the entity tag from the result.
1289 *eTagValue = ProcessXMLEntryETag();
1291 // Restore the original settings.
1293 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1294 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1295 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1296 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1297 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1298 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1299 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1301 return serverResult;
1305 CalDAVServerResult CalDAV::AddEntry(string *calendarEntryHREF, string *entryData){
1307 // Add an entry to the calendar collection.
1309 CalDAVServerResult serverResult;
1310 CalDAVSendData entryAddSendData;
1312 // Build the calendar list address.
1314 string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1316 entryAddSendData.readptr = entryData;
1317 entryAddSendData.sizeleft = entryData->size();
1319 struct curl_slist *calendarRequestHeader = NULL;
1321 calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1323 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
1324 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
1325 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1326 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1327 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
1328 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1330 // Process the data.
1333 serverHeader.clear();
1335 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1337 if (serverConnectionResult == CURLE_OK){
1338 serverResult.result = CALDAVQUERYRESULT_OK;
1340 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1342 serverResult.code = serverConnectionResult;
1343 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1345 // Restore the original settings.
1347 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1348 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1349 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1350 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1351 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1352 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1353 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1355 return serverResult;
1359 CalDAVServerResult CalDAV::EditEntry(string *calendarEntryHREF, string *entryData, string *entryETag){
1361 // Edit an entry in the calendar collection.
1363 // Add an entry to the calendar collection.
1365 CalDAVServerResult serverResult;
1366 CalDAVSendData entryAddSendData;
1368 // Build the calendar list address.
1370 string entryAddURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1372 entryAddSendData.readptr = entryData;
1373 entryAddSendData.sizeleft = entryData->size();
1375 string ifMatchHeader = "If-Match: \"";
1376 ifMatchHeader.append(*entryETag);
1377 ifMatchHeader.append("\"");
1379 struct curl_slist *calendarRequestHeader = NULL;
1381 calendarRequestHeader = curl_slist_append(calendarRequestHeader, "Content-Type: text/calendar; charset=utf-8");
1382 calendarRequestHeader = curl_slist_append(calendarRequestHeader, ifMatchHeader.c_str());
1384 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, calendarRequestHeader);
1385 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryAddURLAddress.c_str());
1386 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "PUT");
1387 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 1L);
1388 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &entryAddSendData);
1389 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, CalDAVSend);
1391 // Process the data.
1394 serverHeader.clear();
1396 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1398 if (serverConnectionResult == CURLE_OK){
1399 serverResult.result = CALDAVQUERYRESULT_OK;
1401 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1403 serverResult.code = serverConnectionResult;
1404 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1406 // Restore the original settings.
1408 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1409 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1410 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1411 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1412 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1413 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1414 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1416 return serverResult;
1420 CalDAVServerResult CalDAV::DeleteEntry(string *calendarEntryHREF){
1422 // Delete an entry in the calendar collection.
1424 CalDAVServerResult serverResult;
1426 // Build the calendar list address.
1428 string entryDeleteURLAddress = BuildServerAddress(&connectionData, (*calendarEntryHREF));
1430 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1431 curl_easy_setopt(connectionHandle, CURLOPT_URL, entryDeleteURLAddress.c_str());
1432 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
1434 // Delete the calendar.
1437 serverHeader.clear();
1439 CURLcode serverConnectionResult = curl_easy_perform(connectionHandle);
1441 if (serverConnectionResult == CURLE_OK){
1442 serverResult.result = CALDAVQUERYRESULT_OK;
1444 serverResult.result = CALDAVQUERYRESULT_SERVERERROR;
1446 serverResult.code = serverConnectionResult;
1447 curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &serverResult.httpCode);
1449 // Restore the original settings.
1451 string originalServerAddress = BuildServerAddress(&connectionData, "/principals/");
1452 curl_easy_setopt(connectionHandle, CURLOPT_URL, originalServerAddress.c_str());
1453 curl_easy_setopt(connectionHandle, CURLOPT_CUSTOMREQUEST, NULL);
1454 curl_easy_setopt(connectionHandle, CURLOPT_UPLOAD, 0L);
1455 curl_easy_setopt(connectionHandle, CURLOPT_READDATA, NULL);
1456 curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, NULL);
1457 curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, NULL);
1459 return serverResult;
1463 bool CalDAVObjectValidSettings(CalDAVConnectionData *connData){
1465 // Check if the passed CalDAV Connection Data is has
1466 // an address set. Return false if nullptr is used.
1468 if (connData == nullptr){
1474 // Check the server hostname. Return false
1475 // if no value has been set.
1477 if (connData->hostname.size() == 0){
1483 // Check the server port. Return false if
1484 // no value has been set or the port number
1485 // is less than 1 or higher than 65535.
1487 if (connData->port < 1 || connData->port > 65535){
1493 // Check the server username. Return false
1494 // if no value has been set.
1496 if (connData->username.size() == 0){
1502 // Check the server password. Return false
1503 // if no value has been set.
1505 if (connData->password.size() == 0){
1511 // Cannot check UseSSL: It is either true
1514 // Cannot check Prefix: The prefix may need
1515 // to be worked out first.
1517 // No errors were found whilst checking so
1524 string BuildServerAddress(CalDAVConnectionData *connData, string uriAddress){
1526 string serverAddress;
1528 // Setup the server address.
1530 if (connData->useSSL == true){
1531 serverAddress += "https://";
1533 serverAddress += "http://";
1536 serverAddress += connData->hostname;
1538 // Check if server port is 80, otherwise
1539 // specifiy the port number in the address.
1541 if (connData->port != 80){
1542 serverAddress += ":";
1543 serverAddress += to_string(connData->port);
1546 serverAddress += uriAddress;
1548 return serverAddress;