]> code.citadel.org Git - citadel.git/blob - webcit/groupdav_get.c
GroupDAV 'GET' operation now loads the message into
[citadel.git] / webcit / groupdav_get.c
1 /*
2  * $Id$
3  *
4  * Handles GroupDAV GET requests.
5  *
6  */
7
8 #include "webcit.h"
9 #include "webserver.h"
10 #include "groupdav.h"
11
12
13 /*
14  * Fetch the entire contents of the room as one big ics file.
15  * This is for "webcal://" type access.
16  */     
17 void groupdav_get_big_ics(void) {
18         char buf[1024];
19
20         serv_puts("ICAL getics");
21         serv_getln(buf, sizeof buf);
22         if (buf[0] != '1') {
23                 wprintf("HTTP/1.1 404 not found\r\n");
24                 groupdav_common_headers();
25                 wprintf(
26                         "Content-Type: text/plain\r\n"
27                         "\r\n"
28                         "%s\r\n",
29                         &buf[4]
30                 );
31                 return;
32         }
33
34         wprintf("HTTP/1.1 200 OK\r\n");
35         groupdav_common_headers();
36         wprintf("Content-type: text/calendar; charset=UTF-8\r\n");
37         begin_burst();
38         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
39                 wprintf("%s\r\n", buf);
40         }
41         end_burst();
42 }
43
44
45 /*
46  * The pathname is always going to take one of two formats:
47  * /groupdav/room_name/euid     (GroupDAV)
48  * /groupdav/room_name          (webcal)
49  */
50 void groupdav_get(char *dav_pathname) {
51         char dav_roomname[1024];
52         char dav_uid[1024];
53         long dav_msgnum = (-1);
54         char buf[1024];
55         int in_body = 0;
56         int found_content_type = 0;
57
58         if (num_tokens(dav_pathname, '/') < 3) {
59                 wprintf("HTTP/1.1 404 not found\r\n");
60                 groupdav_common_headers();
61                 wprintf(
62                         "Content-Type: text/plain\r\n"
63                         "\r\n"
64                         "The object you requested was not found.\r\n"
65                 );
66                 return;
67         }
68
69         extract_token(dav_roomname, dav_pathname, 2, '/', sizeof dav_roomname);
70         extract_token(dav_uid, dav_pathname, 3, '/', sizeof dav_uid);
71         if ((!strcasecmp(dav_uid, "ics")) || (!strcasecmp(dav_uid, "calendar.ics"))) {
72                 strcpy(dav_uid, "");
73         }
74
75         /* Go to the correct room. */
76         if (strcasecmp(WC->wc_roomname, dav_roomname)) {
77                 gotoroom(dav_roomname);
78         }
79         if (strcasecmp(WC->wc_roomname, dav_roomname)) {
80                 wprintf("HTTP/1.1 404 not found\r\n");
81                 groupdav_common_headers();
82                 wprintf(
83                         "Content-Type: text/plain\r\n"
84                         "\r\n"
85                         "There is no folder called \"%s\" on this server.\r\n",
86                         dav_roomname
87                 );
88                 return;
89         }
90
91         /** GET on the collection itself returns an ICS of the entire collection.
92          */
93         if (!strcasecmp(dav_uid, "")) {
94                 groupdav_get_big_ics();
95                 return;
96         }
97
98         dav_msgnum = locate_message_by_uid(dav_uid);
99         serv_printf("MSG2 %ld", dav_msgnum);
100         serv_getln(buf, sizeof buf);
101         if (buf[0] != '1') {
102                 wprintf("HTTP/1.1 404 not found\r\n");
103                 groupdav_common_headers();
104                 wprintf(
105                         "Content-Type: text/plain\r\n"
106                         "\r\n"
107                         "Object \"%s\" was not found in the \"%s\" folder.\r\n",
108                         dav_uid,
109                         dav_roomname
110                 );
111                 return;
112         }
113
114         /* We got it; a message is now arriving from the server.  Read it in. */
115
116         char *msgtext = NULL;
117         size_t msglen = 0;
118         size_t msgalloc = 0;
119         int linelen;
120
121         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
122                 linelen = strlen(buf);
123                 if ((msglen + linelen + 3) > msgalloc) {
124                         msgalloc = ( (msgalloc > 0) ? (msgalloc * 2) : 1024 );
125                         msgtext = realloc(msgtext, msgalloc);
126                 }
127                 strcpy(&msgtext[msglen], buf);
128                 msglen += linelen;
129                 strcpy(&msgtext[msglen], "\n");
130                 msglen += 1;
131         }
132         msgtext[msglen] = 0;
133
134         /* Now do something with it.  FIXME boil it down to only the part we need */
135
136         char *ptr = msgtext;
137         char *endptr = &msgtext[msglen];
138
139         wprintf("HTTP/1.1 200 OK\r\n");
140         groupdav_common_headers();
141         wprintf("etag: \"%ld\"\r\n", dav_msgnum);
142
143         do {
144                 ptr = memreadline(ptr, buf, sizeof buf);
145
146                 if (in_body) {
147                         wprintf("%s\r\n", buf);
148                 }
149                 else if (!strncasecmp(buf, "Date: ", 6)) {
150                         wprintf("%s\r\n", buf);
151                 }
152                 else if (!strncasecmp(buf, "Content-type:", 13)) {
153                         /* wprintf("%s", buf); */
154                         if (bmstrcasestr(buf, "charset=")) {
155                                 wprintf("%s\r\n", buf);
156                         }
157                         else {
158                                 wprintf("%s;charset=UTF-8\r\n", buf);
159                         }
160                         found_content_type = 1;
161                 }
162                 else if ((strlen(buf) == 0) && (in_body == 0)) {
163                         if (!found_content_type) {
164                                 wprintf("Content-type: text/plain\r\n");
165                         }
166                         in_body = 1;
167                         begin_burst();
168                 }
169         } while (ptr < endptr);
170
171         end_burst();
172
173         free(msgtext);
174 }