4 * Handles GroupDAV GET requests.
14 * Fetch the entire contents of the room as one big ics file.
15 * This is for "webcal://" type access.
17 void groupdav_get_big_ics(void) {
20 serv_puts("ICAL getics");
21 serv_getln(buf, sizeof buf);
23 hprintf("HTTP/1.1 404 not found\r\n");
24 groupdav_common_headers();
25 hprintf("Content-Type: text/plain\r\n");
28 );/// TODO: do we need to end-burst here?
32 hprintf("HTTP/1.1 200 OK\r\n");
33 groupdav_common_headers();
34 hprintf("Content-type: text/calendar; charset=UTF-8\r\n");
36 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
37 wprintf("%s\r\n", buf);
44 * MIME parser callback function for groupdav_get()
45 * Helps identify the relevant section of a multipart message
47 void extract_preferred(char *name, char *filename, char *partnum, char *disp,
48 void *content, char *cbtype, char *cbcharset,
49 size_t length, char *encoding, void *userdata)
51 struct epdata *epdata = (struct epdata *)userdata;
54 /* We only want the first one that we found */
55 if (!IsEmptyStr(epdata->found_section)) return;
57 /* Check for a content type match */
58 if (strlen(epdata->desired_content_type_1) > 0) {
59 if (!strcasecmp(epdata->desired_content_type_1, cbtype)) {
63 if (!IsEmptyStr(epdata->desired_content_type_2)) {
64 if (!strcasecmp(epdata->desired_content_type_2, cbtype)) {
69 /* Is this the one? If so, output it. */
71 safestrncpy(epdata->found_section, partnum, sizeof epdata->found_section);
72 if (!IsEmptyStr(cbcharset)) {
73 safestrncpy(epdata->charset, cbcharset, sizeof epdata->charset);
75 hprintf("Content-type: %s; charset=%s\r\n", cbtype, epdata->charset);
77 StrBufAppendBufPlain(WC->WBuf, content, length, 0);
85 * The pathname is always going to take one of two formats:
86 * /groupdav/room_name/euid (GroupDAV)
87 * /groupdav/room_name (webcal)
89 void groupdav_get(char *dav_pathname) {
90 char dav_roomname[1024];
92 long dav_msgnum = (-1);
95 int found_content_type = 0;
102 char content_type[128];
105 struct epdata epdata;
107 if (num_tokens(dav_pathname, '/') < 3) {
108 hprintf("HTTP/1.1 404 not found\r\n");
109 groupdav_common_headers();
110 hprintf("Content-Type: text/plain\r\n");
111 wprintf("The object you requested was not found.\r\n");
116 extract_token(dav_roomname, dav_pathname, 2, '/', sizeof dav_roomname);
117 extract_token(dav_uid, dav_pathname, 3, '/', sizeof dav_uid);
118 if ((!strcasecmp(dav_uid, "ics")) || (!strcasecmp(dav_uid, "calendar.ics"))) {
122 /* Go to the correct room. */
123 if (strcasecmp(WC->wc_roomname, dav_roomname)) {
124 gotoroom(dav_roomname);
126 if (strcasecmp(WC->wc_roomname, dav_roomname)) {
127 hprintf("HTTP/1.1 404 not found\r\n");
128 groupdav_common_headers();
129 hprintf("Content-Type: text/plain\r\n");
130 wprintf("There is no folder called \"%s\" on this server.\r\n",
136 /** GET on the collection itself returns an ICS of the entire collection.
138 if (!strcasecmp(dav_uid, "")) {
139 groupdav_get_big_ics();
143 dav_msgnum = locate_message_by_uid(dav_uid);
144 serv_printf("MSG2 %ld", dav_msgnum);
145 serv_getln(buf, sizeof buf);
147 hprintf("HTTP/1.1 404 not found\r\n");
148 groupdav_common_headers();
149 hprintf("Content-Type: text/plain\r\n");
150 wprintf("Object \"%s\" was not found in the \"%s\" folder.\r\n",
157 /* We got it; a message is now arriving from the server. Read it in. */
160 found_content_type = 0;
161 strcpy(charset, "UTF-8");
162 strcpy(content_type, "text/plain");
164 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
165 linelen = strlen(buf);
167 /* Append it to the buffer */
168 if ((msglen + linelen + 3) > msgalloc) {
169 msgalloc = ( (msgalloc > 0) ? (msgalloc * 2) : 1024 );
170 msgtext = realloc(msgtext, msgalloc);
172 strcpy(&msgtext[msglen], buf);
174 strcpy(&msgtext[msglen], "\n");
177 /* Also learn some things about the message */
182 if (!strncasecmp(buf, "Date:", 5)) {
183 safestrncpy(date, &buf[5], sizeof date);
186 if (!strncasecmp(buf, "Content-type:", 13)) {
187 safestrncpy(content_type, &buf[13], sizeof content_type);
188 striplt(content_type);
189 ptr = bmstrcasestr(&buf[13], "charset=");
191 safestrncpy(charset, ptr+8, sizeof charset);
193 endptr = strchr(charset, ';');
194 if (endptr != NULL) strcpy(endptr, "");
196 endptr = strchr(content_type, ';');
197 if (endptr != NULL) strcpy(endptr, "");
203 /* Output headers common to single or multi part messages */
205 hprintf("HTTP/1.1 200 OK\r\n");
206 groupdav_common_headers();
207 hprintf("etag: \"%ld\"\r\n", dav_msgnum);
208 hprintf("Date: %s\r\n", date);
210 memset(&epdata, 0, sizeof(struct epdata));
211 safestrncpy(epdata.charset, charset, sizeof epdata.charset);
213 /* If we have a multipart message on our hands, and we are in a groupware room,
214 * strip it down to only the relevant part.
216 if (!strncasecmp(content_type, "multipart/", 10)) {
218 if ( (WC->wc_default_view == VIEW_CALENDAR) || (WC->wc_default_view == VIEW_TASKS) ) {
219 strcpy(epdata.desired_content_type_1, "text/calendar");
222 else if (WC->wc_default_view == VIEW_ADDRESSBOOK) {
223 strcpy(epdata.desired_content_type_1, "text/vcard");
224 strcpy(epdata.desired_content_type_2, "text/x-vcard");
227 mime_parser(msgtext, &msgtext[msglen], extract_preferred, NULL, NULL, (void *)&epdata, 0);
230 /* If epdata.found_section is empty, we haven't output anything yet, so output the whole thing */
232 if (IsEmptyStr(epdata.found_section)) {
234 endptr = &msgtext[msglen];
236 hprintf("Content-type: %s; charset=%s\r\n", content_type, charset);
240 ptr = memreadline(ptr, buf, sizeof buf);
243 wprintf("%s\r\n", buf);
245 else if ((buf[0] == 0) && (in_body == 0)) {
249 } while (ptr < endptr);