795794108e7c1af90461fae0b75601037dcf9408
[citadel.git] / webcit / dav_options.c
1 /*
2  * Handles DAV OPTIONS requests (experimental -- not required by GroupDAV)
3  *
4  * Copyright (c) 2005-2012 by the citadel.org team
5  *
6  * This program is open source software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version 3.
8  * 
9  * 
10  *
11  * This program 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  * 
17  * 
18  * 
19  */
20
21 #include "webcit.h"
22 #include "webserver.h"
23 #include "dav.h"
24
25 /*
26  * The pathname is always going to be /groupdav/room_name/msg_num
27  */
28 void dav_options(void)
29 {
30         wcsession *WCC = WC;
31         StrBuf *dav_roomname;
32         StrBuf *dav_uid;
33         long dav_msgnum = (-1);
34         char datestring[256];
35         time_t now;
36
37         now = time(NULL);
38         http_datestring(datestring, sizeof datestring, now);
39
40         dav_roomname = NewStrBuf();
41         dav_uid = NewStrBuf();
42         StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
43         StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
44
45         syslog(LOG_DEBUG, "\033[35m%s (logged_in=%d)\033[0m", ChrPtr(WCC->Hdr->HR.ReqLine), WC->logged_in);
46         /*
47          * If the room name is blank, the client is doing an OPTIONS on the root.
48          */
49         if (StrLength(dav_roomname) == 0) {
50                 syslog(LOG_DEBUG, "\033[36mOPTIONS requested for root\033[0m");
51                 hprintf("HTTP/1.1 200 OK\r\n");
52                 dav_common_headers();
53                 hprintf("Date: %s\r\n", datestring);
54                 hprintf("DAV: 1\r\n");
55                 hprintf("Allow: OPTIONS, PROPFIND\r\n");
56                 hprintf("\r\n");
57                 begin_burst();
58                 end_burst();
59                 FreeStrBuf(&dav_roomname);
60                 FreeStrBuf(&dav_uid);
61                 return;
62         }
63
64         /* Go to the correct room. */
65         if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
66                 gotoroom(dav_roomname);
67         }
68
69         if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
70                 syslog(LOG_DEBUG, "\033[36mOPTIONS requested for invalid item\033[0m");
71                 hprintf("HTTP/1.1 404 not found\r\n");
72                 dav_common_headers();
73                 hprintf("Date: %s\r\n", datestring);
74                 hprintf(
75                         "Content-Type: text/plain\r\n");
76                 begin_burst();
77                 wc_printf(
78                         "There is no folder called \"%s\" on this server.\r\n",
79                         ChrPtr(dav_roomname)
80                 );
81                 end_burst();
82                 FreeStrBuf(&dav_roomname);
83                 FreeStrBuf(&dav_uid);
84                 return;
85         }
86
87         /* If dav_uid is non-empty, client is requesting an OPTIONS on
88          * a specific item in the room.
89          */
90         if (StrLength(dav_uid) != 0) {
91                 syslog(LOG_DEBUG, "\033[36mOPTIONS requested for specific item\033[0m");
92                 dav_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
93                 if (dav_msgnum < 0) {
94                         hprintf("HTTP/1.1 404 not found\r\n");
95                         dav_common_headers();
96                         hprintf("Content-Type: text/plain\r\n");
97                         begin_burst();
98                         wc_printf(
99                                 "Object \"%s\" was not found in the \"%s\" folder.\r\n",
100                                 ChrPtr(dav_uid),
101                                 ChrPtr(dav_roomname)
102                         );
103                         FreeStrBuf(&dav_roomname);
104                         FreeStrBuf(&dav_uid);
105                         end_burst();return;
106                 }
107
108                 hprintf("HTTP/1.1 200 OK\r\n");
109                 dav_common_headers();
110                 hprintf("Date: %s\r\n", datestring);
111                 hprintf("DAV: 1\r\n");
112                 hprintf("Allow: OPTIONS, PROPFIND, GET, PUT, DELETE\r\n");
113                 
114                 begin_burst();
115                 end_burst();
116                 FreeStrBuf(&dav_roomname);
117                 FreeStrBuf(&dav_uid);
118                 return;
119         }
120
121         FreeStrBuf(&dav_roomname);
122         FreeStrBuf(&dav_uid);
123
124         /*
125          * We got to this point, which means that the client is requesting
126          * an OPTIONS on the room itself.
127          */
128         syslog(LOG_DEBUG, "\033[36mOPTIONS requested for room '%s' (%slogged in)\033[0m",
129                 ChrPtr(WC->CurRoom.name),
130                 ((WC->logged_in) ? "" : "not ")
131         );
132         hprintf("HTTP/1.1 200 OK\r\n");
133         dav_common_headers();
134         hprintf("Date: %s\r\n", datestring);
135
136         /*
137          * Offer CalDAV (RFC 4791) if this is a calendar room
138          */
139         if ( (WC->CurRoom.view == VIEW_CALENDAR) || (WC->CurRoom.view == VIEW_CALBRIEF) ) {
140                 hprintf("DAV: 1, calendar-access\r\n");
141                 syslog(LOG_DEBUG, "\033[36mDAV: 1, calendar-access\033[0m");
142         }
143         else {
144                 hprintf("DAV: 1\r\n");
145                 syslog(LOG_DEBUG, "\033[36mDAV: 1\033[0m");
146         }
147
148         hprintf("Allow: OPTIONS, PROPFIND, GET, PUT, REPORT\r\n");
149         begin_burst();
150         end_burst();
151 }