Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Added the GetServerResult subroutine in the CalDAV object.
[xestiacalendar/.git] / source / objects / CalDAV / CalDAV.cpp
1 // CalDAV.cpp - CalDAV Connection Object.
2 //
3 // (c) 2016 Xestia Software Development.
4 //
5 // This file is part of Xestia Calendar.
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 Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalDAV.h"
21 using namespace std;
23 size_t CalDAVReceive(char *ReceivedBuffer, size_t Size, size_t NewMemoryBytes, string *StringPointer)
24 {
25         
26         string ReceivedBufferString = "";
27         ReceivedBufferString.append(ReceivedBuffer, NewMemoryBytes);
28         
29         StringPointer->append(ReceivedBufferString);
30         
31         return Size * NewMemoryBytes;
32         
33 }
35 size_t CalDAVSend(char *SendBuffer, size_t Size, size_t NewMemoryBytes, void *DataStruct){
37         struct CalDAVSendData *UploadPtr = (struct CalDAVSendData *)DataStruct;
38         
39         if (UploadPtr->sizeleft){
41                 UploadPtr->sizeleft--;
42                 char CharSend;
44                 CharSend = (*UploadPtr->readptr)[UploadPtr->seek];
45                 
46                 *SendBuffer = CharSend;
47                 
48                 UploadPtr->seek++;
50                 return 1;
52         }
54         return 0;
56 }
58 CalDAV::CalDAV(){
60         // Setup the objects within the CalDAV connection 
61         // object.
62         
63         ConnectionHandle = curl_easy_init();
64         
65 }
67 CalDAV::~CalDAV(){
68         
69         // Destory the objects within the CalDAV connection
70         // object.
71         
72         curl_easy_cleanup(ConnectionHandle);
73         ConnectionHandle = nullptr;
74         
75 }
77 void CalDAV::SetupConnectionData(CalDAVConnectionData *ConnData){
78         
79         // Check if ConnData is a nullptr, return if it is.
80         
81         if (ConnData == nullptr){
82                 return;
83         }
84         
85         // Set the connection settings to the values from ConnData.
87         ConnectionData = (*ConnData);
88         
89 }
91 CalDAVStatus CalDAV::GetConnectionData(){
92         
93         // Get the current connection settings for the CalDAV
94         // connection object and return a CalDAVStatus object.
95         
96         CalDAVStatus ConnectionStatus;
97         
98         ConnectionStatus.Hostname = ConnectionData.Hostname;
99         ConnectionStatus.Port = ConnectionData.Port;
100         ConnectionStatus.Username = ConnectionData.Username;
101         ConnectionStatus.Prefix = ConnectionData.Prefix;
102         ConnectionStatus.UseSSL = ConnectionData.UseSSL;
103         ConnectionStatus.Timeout = ConnectionData.Timeout;
104         
105         return ConnectionStatus;
106         
109 CalDAVServerResult CalDAV::Connect(){
111         CalDAVServerResult ServerResult;
113         string ServerAddress = "";
114         string ServerUserPass = "";
116         // Setup the server address.
117         
118         ServerAddress = BuildServerAddress(&ConnectionData, "/principals/");
120         // Setup the server password.
121         
122         ServerUserPass += ConnectionData.Username;
123         ServerUserPass += ":";
124         ServerUserPass += ConnectionData.Password;
125         
126         curl_easy_setopt(ConnectionHandle, CURLOPT_URL, ServerAddress.c_str());
127         curl_easy_setopt(ConnectionHandle, CURLOPT_USERPWD, ServerUserPass.c_str());
128         curl_easy_setopt(ConnectionHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
129         curl_easy_setopt(ConnectionHandle, CURLOPT_FAILONERROR, 1L);
130         curl_easy_setopt(ConnectionHandle, CURLOPT_TIMEOUT, ConnectionData.Timeout);
131         curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEFUNCTION, CalDAVReceive);
132         curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEDATA, &ServerData);
133         curl_easy_setopt(ConnectionHandle, CURLOPT_WRITEHEADER, &ServerHeader);
134         
135         // Connect to the CalDAV server.
136         
137         ServerResult.Code = curl_easy_perform(ConnectionHandle);
139         // Process the result received from the server.
140         
141         if (ServerResult.Code != CURLE_OK){
142                 
143                 ServerResult.Result = CALDAVQUERYRESULT_SERVERERROR;
144                 
145         } else {
146                 
147                 ServerResult.Result = CALDAVQUERYRESULT_OK;
148                 
149         }
150         
151         // Get the HTTP code.
152         
153         curl_easy_getinfo(ConnectionHandle, CURLINFO_RESPONSE_CODE, &ServerResult.HTTPCode);
154         
155         return ServerResult;
156         
159 CalDAVServerResult CalDAV::GetServerResult(){
160         
161         return ConnectionServerResult;
162         
165 CalDAVServerSupport CalDAV::GetServerSupport(){
167         CalDAVServerSupport ServerStatus;
168         
169         // Setup the server connection.
170         
171         curl_easy_setopt(ConnectionHandle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
172         
173         CURLcode ServerResult = curl_easy_perform(ConnectionHandle);
174         
175         if (ServerResult != CURLE_OK){
176                 return ServerStatus;
177         }
178         
179         // Check that the server header has data in,
180         // otherwise return an "empty" CalDAVServerSupport.
181         
182         if (ServerHeader.size() == 0){
183                 return ServerStatus;
184         }
185         
186         // Process each line looking for the first DAV header 
187         // line.
188         
189         bool NewlineMode = true;
190         
191         string DAVLine;
192         
193         for (int CharSeek = 0; CharSeek < ServerHeader.size(); CharSeek++){
194                 
195                 if (NewlineMode == true){
196                         
197                         // Check if we have reached the end of the string.
198                         
199                         if (CharSeek >= ServerHeader.size()){
200                                 
201                                 break;
202                                 
203                         }
204                         
205                         // Check the first four letters to make sure
206                         // they are 'DAV:'.
207                         
208                         string DAVHeaderCheck = "";
209                         
210                         try {
211                                 DAVHeaderCheck = ServerHeader.substr(CharSeek, 4);
212                         }
213                         
214                         catch (out_of_range &oor){
215                                 break;
216                         }
217                         
218                         if (DAVHeaderCheck == "DAV:"){
219                                 
220                                 CharSeek += 5;
221                                 
222                                 for (; CharSeek < ServerHeader.size(); CharSeek++){
223                                         
224                                         if (ServerHeader[CharSeek] == '\n'){
225                                         
226                                                 break;
227                                                 
228                                         }
229                                         
230                                         DAVLine.push_back(ServerHeader[CharSeek]);
231                                         
232                                 }
233                                 
234                                 break;
235                                 
236                         }
237                         
238                         NewlineMode = false;
239                         
240                 }
241                 
242                 if (ServerHeader[CharSeek] == '\n'){
243                         
244                         NewlineMode = true;
245                         
246                 }
247                 
248         }
249         
250         // Process the DAV line.
251         
252         vector<string> DAVLineData;
253         string DAVSegmentString;
254         
255         for (int CharSeek = 0; CharSeek < DAVLine.size(); CharSeek++){
256                 
257                 if (DAVLine[CharSeek] == ' '){
258                         continue;
259                 }
260                 
261                 if (DAVLine[CharSeek] == ','){
262                         
263                         DAVLineData.push_back(DAVSegmentString);
264                         DAVSegmentString.clear();
265                         continue;
266                         
267                 }
268                 
269                 DAVSegmentString += DAVLine[CharSeek];
270                 
271         }
272         
273         // Process the DAV values and set each value
274         // to true as required.
275         
276         for (int DAVItemSeek = 0; 
277                 DAVItemSeek < DAVLineData.size();
278                 DAVItemSeek++){
279                         
280                 if (DAVLineData.at(DAVItemSeek) == "calendar-access"){
281                         
282                         ServerStatus.BasicSupport = true;
283                 
284                 }
285                         
286         }
287         
288         return ServerStatus;
289         
292 bool CalDAVObjectValidSettings(CalDAVConnectionData *ConnData){
294         // Check if the passed CalDAV Connection Data is has
295         // an address set. Return false if nullptr is used.
297         if (ConnData == nullptr){
298         
299                 return false;
300         
301         }
302         
303         // Check the server hostname. Return false
304         // if no value has been set.
305         
306         if (ConnData->Hostname.size() == 0){
307         
308                 return false;
309         
310         }
311         
312         // Check the server port. Return false if
313         // no value has been set or the port number
314         // is less than 1 or higher than 65535.
315         
316         if (ConnData->Port < 1 || ConnData->Port > 65535){
317         
318                 return false;
319         
320         }
321         
322         // Check the server username. Return false
323         // if no value has been set.
324         
325         if (ConnData->Username.size() == 0){
326                 
327                 return false;
328                 
329         }       
330         
331         // Check the server password. Return false
332         // if no value has been set.
333         
334         if (ConnData->Password.size() == 0){
335                 
336                 return false;
337                 
338         }
340         // Cannot check UseSSL: It is either true
341         // or false.
342         
343         // Cannot check Prefix: The prefix may need
344         // to be worked out first.
346         // No errors were found whilst checking so
347         // return true.
348         
349         return true;
353 string BuildServerAddress(CalDAVConnectionData *ConnData, string URIAddress){
354         
355         string ServerAddress;
356         
357         // Setup the server address.
358         
359         if (ConnData->UseSSL == true){
360                 ServerAddress += "https://";
361         } else {
362                 ServerAddress += "http://";
363         }
364         
365         ServerAddress += ConnData->Hostname;
366         
367         // Check if server port is 80, otherwise
368         // specifiy the port number in the address.
369         
370         if (ConnData->Port != 80){
371                 ServerAddress += ":";
372                 ServerAddress += to_string(ConnData->Port);
373         }
374         
375         ServerAddress += URIAddress;
376         
377         return ServerAddress;
378         
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