4 * This is the main transaction loop of the web service. It maintains a
5 * persistent session to the Citadel server, handling HTTP WebCit requests as
6 * they arrive and presenting a user interface.
20 #include "webserver.h"
23 HashList *StaticFilemappings[4] = {NULL, NULL, NULL, NULL};
26 lprintf(9, "Suspicious request. Ignoring.");
27 hprintf("HTTP/1.1 404 Security check failed\r\n");
28 hprintf("Content-Type: text/plain\r\n\r\n");
29 wc_printf("You have sent a malformed or invalid request.\r\n");
34 * dump out static pages from disk
36 void output_static(const char *what)
42 const char *content_type;
46 fd = open(what, O_RDONLY);
48 lprintf(9, "output_static('%s') [%s] -- NOT FOUND --\n", what, ChrPtr(WC->Hdr->this_page));
49 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
50 hprintf("Content-Type: text/plain\r\n");
52 wc_printf("Cannot open %s: %s\r\n", what, strerror(errno));
56 content_type = GuessMimeByFilename(what, len);
58 if (fstat(fd, &statbuf) == -1) {
59 lprintf(9, "output_static('%s') -- FSTAT FAILED --\n", what);
60 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
61 hprintf("Content-Type: text/plain\r\n");
63 wc_printf("Cannot fstat %s: %s\n", what, strerror(errno));
69 bytes = statbuf.st_size;
71 if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0)
73 if (fd > 0) close(fd);
74 lprintf(9, "output_static('%s') -- FREAD FAILED (%s) --\n", what, strerror(errno));
75 hprintf("HTTP/1.1 500 internal server error \r\n");
76 hprintf("Content-Type: text/plain\r\n");
84 lprintf(9, "output_static('%s') %s\n", what, content_type);
86 http_transmit_thing(content_type, 2);
88 if (yesbstr("force_close_session")) {
94 int LoadStaticDir(const char *DirName, HashList *DirList, const char *RelDir)
96 char dirname[PATH_MAX];
97 char reldir[PATH_MAX];
98 StrBuf *FileName = NULL;
100 StrBuf *WebDir = NULL;
101 StrBuf *OneWebName = NULL;
104 struct dirent *filedir_entry;
110 filedir = opendir (DirName);
111 if (filedir == NULL) {
115 d = (struct dirent *)malloc(offsetof(struct dirent, d_name) + PATH_MAX + 1);
120 Dir = NewStrBufPlain(DirName, -1);
121 WebDir = NewStrBufPlain(RelDir, -1);
122 istoplevel = IsEmptyStr(RelDir);
123 OneWebName = NewStrBuf();
125 while ((readdir_r(filedir, d, &filedir_entry) == 0) &&
126 (filedir_entry != NULL))
129 #ifdef _DIRENT_HAVE_D_NAMELEN
130 d_namelen = filedir_entry->d_namelen;
131 d_type = filedir_entry->d_type;
140 #define IFTODT(mode) (((mode) & 0170000) >> 12)
141 #define DTTOIF(dirtype) ((dirtype) << 12)
143 d_namelen = strlen(filedir_entry->d_name);
146 d_without_ext = d_namelen;
148 if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
149 continue; /* Ignore backup files... */
151 if ((d_namelen == 1) &&
152 (filedir_entry->d_name[0] == '.'))
155 if ((d_namelen == 2) &&
156 (filedir_entry->d_name[0] == '.') &&
157 (filedir_entry->d_name[1] == '.'))
160 if (d_type == DT_UNKNOWN) {
163 snprintf(path, PATH_MAX, "%s/%s",
164 DirName, filedir_entry->d_name);
165 if (stat(path, &s) == 0) {
166 d_type = IFTODT(s.st_mode);
173 /* Skip directories we are not interested in... */
174 if ((strcmp(filedir_entry->d_name, ".svn") == 0) ||
175 (strcmp(filedir_entry->d_name, "t") == 0))
177 snprintf(dirname, PATH_MAX, "%s/%s/",
178 DirName, filedir_entry->d_name);
180 snprintf(reldir, PATH_MAX, "%s/",
181 filedir_entry->d_name);
183 snprintf(reldir, PATH_MAX, "%s/%s/",
184 RelDir, filedir_entry->d_name);
185 StripSlashes(dirname, 1);
186 StripSlashes(reldir, 1);
187 LoadStaticDir(dirname, DirList, reldir);
189 case DT_LNK: /* TODO: check whether its a file or a directory */
191 PStart = filedir_entry->d_name;
192 FileName = NewStrBufDup(Dir);
193 if (ChrPtr(FileName) [ StrLength(FileName) - 1] != '/')
194 StrBufAppendBufPlain(FileName, "/", 1, 0);
195 StrBufAppendBufPlain(FileName, filedir_entry->d_name, d_namelen, 0);
197 FlushStrBuf(OneWebName);
198 StrBufAppendBuf(OneWebName, WebDir, 0);
199 if ((StrLength(OneWebName) != 0) &&
200 (ChrPtr(OneWebName) [ StrLength(OneWebName) - 1] != '/'))
201 StrBufAppendBufPlain(OneWebName, "/", 1, 0);
202 StrBufAppendBufPlain(OneWebName, filedir_entry->d_name, d_namelen, 0);
204 Put(DirList, SKEY(OneWebName), FileName, HFreeStrBuf);
205 /* lprintf(9, "[%s | %s]\n", ChrPtr(OneWebName), ChrPtr(FileName)); */
217 FreeStrBuf(&OneWebName);
222 void output_flat_static(void)
228 if (GetHash(StaticFilemappings[0], SKEY(WCC->Hdr->HR.Handler->Name), &vFile) &&
231 File = (StrBuf*) vFile;
232 output_static(ChrPtr(vFile));
236 extern void do_404(void);
238 void output_static_safe(HashList *DirList)
244 if (GetHash(DirList, SKEY(WCC->Hdr->HR.ReqLine), &vFile) &&
247 File = (StrBuf*) vFile;
248 output_static(ChrPtr(vFile));
251 lprintf(1, "output_static_safe() file %s not found. \n",
252 ChrPtr(WCC->Hdr->HR.ReqLine));
253 ///TODO: detect image & output blank image
257 void output_static_0(void)
259 output_static_safe(StaticFilemappings[0]);
261 void output_static_1(void)
263 output_static_safe(StaticFilemappings[1]);
265 void output_static_2(void)
267 output_static_safe(StaticFilemappings[2]);
269 void output_static_3(void)
271 output_static_safe(StaticFilemappings[3]);
275 ServerStartModule_STATIC
278 StaticFilemappings[0] = NewHash(1, NULL);
279 StaticFilemappings[1] = NewHash(1, NULL);
280 StaticFilemappings[2] = NewHash(1, NULL);
281 StaticFilemappings[3] = NewHash(1, NULL);
284 ServerShutdownModule_STATIC
287 DeleteHash(&StaticFilemappings[0]);
288 DeleteHash(&StaticFilemappings[1]);
289 DeleteHash(&StaticFilemappings[2]);
290 DeleteHash(&StaticFilemappings[3]);
298 LoadStaticDir(static_dirs[0], StaticFilemappings[0], "");
299 LoadStaticDir(static_dirs[1], StaticFilemappings[1], "");
300 LoadStaticDir(static_dirs[2], StaticFilemappings[2], "");
301 LoadStaticDir(static_dirs[3], StaticFilemappings[3], "");
303 WebcitAddUrlHandler(HKEY("robots.txt"), "", 0, output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
304 WebcitAddUrlHandler(HKEY("favicon.ico"), "", 0, output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
305 WebcitAddUrlHandler(HKEY("static"), "", 0, output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
306 WebcitAddUrlHandler(HKEY("static.local"), "", 0, output_static_1, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
307 WebcitAddUrlHandler(HKEY("tinymce"), "", 0, output_static_2, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
308 WebcitAddUrlHandler(HKEY("tiny_mce"), "", 0, output_static_2, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);