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");
34 hprintf("HTTP/1.1 200 OK\r\n");
35 groupdav_common_headers();
36 hprintf("Content-type: text/calendar; charset=UTF-8\r\n");
38 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
39 wprintf("%s\r\n", buf);
46 * MIME parser callback function for groupdav_get()
47 * Helps identify the relevant section of a multipart message
49 void extract_preferred(char *name, char *filename, char *partnum, char *disp,
50 void *content, char *cbtype, char *cbcharset,
51 size_t length, char *encoding, char *cbid, void *userdata)
53 struct epdata *epdata = (struct epdata *)userdata;
56 /* We only want the first one that we found */
57 if (!IsEmptyStr(epdata->found_section)) return;
59 /* Check for a content type match */
60 if (strlen(epdata->desired_content_type_1) > 0) {
61 if (!strcasecmp(epdata->desired_content_type_1, cbtype)) {
65 if (!IsEmptyStr(epdata->desired_content_type_2)) {
66 if (!strcasecmp(epdata->desired_content_type_2, cbtype)) {
71 /* Is this the one? If so, output it. */
73 safestrncpy(epdata->found_section, partnum, sizeof epdata->found_section);
74 if (!IsEmptyStr(cbcharset)) {
75 safestrncpy(epdata->charset, cbcharset, sizeof epdata->charset);
77 hprintf("Content-type: %s; charset=%s\r\n", cbtype, epdata->charset);
79 StrBufAppendBufPlain(WC->WBuf, content, length, 0);
87 * The pathname is always going to take one of two formats:
88 * /groupdav/room_name/euid (GroupDAV)
89 * /groupdav/room_name (webcal)
91 void groupdav_get(void)
96 long dav_msgnum = (-1);
99 int found_content_type = 0;
102 char *msgtext = NULL;
106 char content_type[128];
109 struct epdata epdata;
111 if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
112 hprintf("HTTP/1.1 404 not found\r\n");
113 groupdav_common_headers();
114 hprintf("Content-Type: text/plain\r\n");
115 wprintf("The object you requested was not found.\r\n");
120 dav_roomname = NewStrBuf();;
121 dav_uid = NewStrBuf();;
122 StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
123 StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
124 if ((!strcasecmp(ChrPtr(dav_uid), "ics")) ||
125 (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
126 FlushStrBuf(dav_uid);
129 /* Go to the correct room. */
130 if (strcasecmp(ChrPtr(WCC->wc_roomname), ChrPtr(dav_roomname))) {
131 gotoroom(dav_roomname);
133 if (strcasecmp(ChrPtr(WCC->wc_roomname), ChrPtr(dav_roomname))) {
134 hprintf("HTTP/1.1 404 not found\r\n");
135 groupdav_common_headers();
136 hprintf("Content-Type: text/plain\r\n");
137 wprintf("There is no folder called \"%s\" on this server.\r\n",
138 ChrPtr(dav_roomname));
140 FreeStrBuf(&dav_roomname);
141 FreeStrBuf(&dav_uid);
145 /** GET on the collection itself returns an ICS of the entire collection.
147 if (StrLength(dav_uid) == 0) {
148 groupdav_get_big_ics();
149 FreeStrBuf(&dav_roomname);
150 FreeStrBuf(&dav_uid);
154 dav_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
155 serv_printf("MSG2 %ld", dav_msgnum);
156 serv_getln(buf, sizeof buf);
158 hprintf("HTTP/1.1 404 not found\r\n");
159 groupdav_common_headers();
160 hprintf("Content-Type: text/plain\r\n");
161 wprintf("Object \"%s\" was not found in the \"%s\" folder.\r\n",
163 ChrPtr(dav_roomname));
165 FreeStrBuf(&dav_roomname);
166 FreeStrBuf(&dav_uid);
169 FreeStrBuf(&dav_roomname);
170 FreeStrBuf(&dav_uid);
172 /* We got it; a message is now arriving from the server. Read it in. */
175 found_content_type = 0;
176 strcpy(charset, "UTF-8");
177 strcpy(content_type, "text/plain");
179 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
180 linelen = strlen(buf);
182 /* Append it to the buffer */
183 if ((msglen + linelen + 3) > msgalloc) {
184 msgalloc = ( (msgalloc > 0) ? (msgalloc * 2) : 1024 );
185 msgtext = realloc(msgtext, msgalloc);
187 strcpy(&msgtext[msglen], buf);
189 strcpy(&msgtext[msglen], "\n");
192 /* Also learn some things about the message */
197 if (!strncasecmp(buf, "Date:", 5)) {
198 safestrncpy(date, &buf[5], sizeof date);
201 if (!strncasecmp(buf, "Content-type:", 13)) {
202 safestrncpy(content_type, &buf[13], sizeof content_type);
203 striplt(content_type);
204 ptr = bmstrcasestr(&buf[13], "charset=");
206 safestrncpy(charset, ptr+8, sizeof charset);
208 endptr = strchr(charset, ';');
209 if (endptr != NULL) strcpy(endptr, "");
211 endptr = strchr(content_type, ';');
212 if (endptr != NULL) strcpy(endptr, "");
218 /* Output headers common to single or multi part messages */
220 hprintf("HTTP/1.1 200 OK\r\n");
221 groupdav_common_headers();
222 hprintf("etag: \"%ld\"\r\n", dav_msgnum);
223 hprintf("Date: %s\r\n", date);
225 memset(&epdata, 0, sizeof(struct epdata));
226 safestrncpy(epdata.charset, charset, sizeof epdata.charset);
228 /* If we have a multipart message on our hands, and we are in a groupware room,
229 * strip it down to only the relevant part.
231 if (!strncasecmp(content_type, "multipart/", 10)) {
233 if ( (WCC->wc_default_view == VIEW_CALENDAR) || (WCC->wc_default_view == VIEW_TASKS) ) {
234 strcpy(epdata.desired_content_type_1, "text/calendar");
237 else if (WCC->wc_default_view == VIEW_ADDRESSBOOK) {
238 strcpy(epdata.desired_content_type_1, "text/vcard");
239 strcpy(epdata.desired_content_type_2, "text/x-vcard");
242 mime_parser(msgtext, &msgtext[msglen], extract_preferred, NULL, NULL, (void *)&epdata, 0);
245 /* If epdata.found_section is empty, we haven't output anything yet, so output the whole thing */
247 if (IsEmptyStr(epdata.found_section)) {
249 endptr = &msgtext[msglen];
251 hprintf("Content-type: %s; charset=%s\r\n", content_type, charset);
255 ptr = memreadline(ptr, buf, sizeof buf);
258 wprintf("%s\r\n", buf);
260 else if ((buf[0] == 0) && (in_body == 0)) {
264 } while (ptr < endptr);