2 * $Id: webcit.c 7459 2009-05-17 08:34:33Z dothebart $
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.
18 #include "webserver.h"
21 HashList *StaticFilemappings[4] = {NULL, NULL, NULL, NULL};
24 lprintf(9, "Suspicious request. Ignoring.");
25 hprintf("HTTP/1.1 404 Security check failed\r\n");
26 hprintf("Content-Type: text/plain\r\n\r\n");
27 wprintf("You have sent a malformed or invalid request.\r\n");
32 * dump out static pages from disk
34 void output_static(const char *what)
40 const char *content_type;
44 fd = open(what, O_RDONLY);
46 lprintf(9, "output_static('%s') [%s] -- NOT FOUND --\n", what, ChrPtr(WC->Hdr->this_page));
47 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
48 hprintf("Content-Type: text/plain\r\n");
49 wprintf("Cannot open %s: %s\r\n", what, strerror(errno));
53 content_type = GuessMimeByFilename(what, len);
55 if (fstat(fd, &statbuf) == -1) {
56 lprintf(9, "output_static('%s') -- FSTAT FAILED --\n", what);
57 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
58 hprintf("Content-Type: text/plain\r\n");
59 wprintf("Cannot fstat %s: %s\n", what, strerror(errno));
65 bytes = statbuf.st_size;
67 if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0)
69 if (fd > 0) close(fd);
70 lprintf(9, "output_static('%s') -- FREAD FAILED (%s) --\n", what, strerror(errno));
71 hprintf("HTTP/1.1 500 internal server error \r\n");
72 hprintf("Content-Type: text/plain\r\n");
80 lprintf(9, "output_static('%s') %s\n", what, content_type);
82 http_transmit_thing(content_type, 1);
84 if (yesbstr("force_close_session")) {
90 int LoadStaticDir(const char *DirName, HashList *DirList, const char *RelDir)
92 char dirname[PATH_MAX];
93 char reldir[PATH_MAX];
94 StrBuf *FileName = NULL;
96 StrBuf *WebDir = NULL;
97 StrBuf *OneWebName = NULL;
100 struct dirent *filedir_entry;
104 filedir = opendir (DirName);
105 if (filedir == NULL) {
109 Dir = NewStrBufPlain(DirName, -1);
110 WebDir = NewStrBufPlain(RelDir, -1);
111 OneWebName = NewStrBuf();
113 while ((readdir_r(filedir, &d, &filedir_entry) == 0) &&
114 (filedir_entry != NULL))
117 #ifdef _DIRENT_HAVE_D_NAMELEN
118 d_namelen = filedir_entry->d_namelen;
120 d_namelen = strlen(filedir_entry->d_name);
122 d_without_ext = d_namelen;
124 if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
125 continue; /* Ignore backup files... */
127 if ((d_namelen == 1) &&
128 (filedir_entry->d_name[0] == '.'))
131 if ((d_namelen == 2) &&
132 (filedir_entry->d_name[0] == '.') &&
133 (filedir_entry->d_name[1] == '.'))
136 switch (filedir_entry->d_type)
139 /* Skip directories we are not interested in... */
140 if ((strcmp(filedir_entry->d_name, ".svn") == 0) ||
141 (strcmp(filedir_entry->d_name, "t") == 0))
143 snprintf(dirname, PATH_MAX, "%s/%s",
144 DirName, filedir_entry->d_name);
145 snprintf(reldir, PATH_MAX, "%s/%s",
146 RelDir, filedir_entry->d_name);
147 LoadStaticDir(dirname, DirList, reldir);
149 case DT_LNK: /* TODO: check whether its a file or a directory */
151 PStart = filedir_entry->d_name;
152 FileName = NewStrBufDup(Dir);
153 if (ChrPtr(FileName) [ StrLength(FileName) - 1] != '/')
154 StrBufAppendBufPlain(FileName, "/", 1, 0);
155 StrBufAppendBufPlain(FileName, filedir_entry->d_name, d_namelen, 0);
157 FlushStrBuf(OneWebName);
158 StrBufAppendBuf(OneWebName, WebDir, 0);
159 if ((StrLength(OneWebName) != 0) &&
160 (ChrPtr(OneWebName) [ StrLength(OneWebName)] != '/'))
161 StrBufAppendBufPlain(OneWebName, "/", 1, 0);
162 StrBufAppendBufPlain(OneWebName, filedir_entry->d_name, d_namelen, 0);
164 Put(DirList, SKEY(OneWebName), FileName, HFreeStrBuf);
165 /* printf("[%s | %s] \n", ChrPtr(OneWebName), ChrPtr(FileName));*/
176 FreeStrBuf(&OneWebName);
181 void output_flat_static(void)
187 if (GetHash(StaticFilemappings[0], SKEY(WCC->Hdr->Handler->Name), &vFile) &&
190 File = (StrBuf*) vFile;
191 output_static(ChrPtr(vFile));
197 void output_static_safe(HashList *DirList)
203 if (GetHash(DirList, SKEY(WCC->Hdr->ReqLine), &vFile) &&
206 File = (StrBuf*) vFile;
207 output_static(ChrPtr(vFile));
210 ///TODO: detect image & output blank image
213 void output_static_0(void)
215 output_static_safe(StaticFilemappings[0]);
217 void output_static_1(void)
219 output_static_safe(StaticFilemappings[1]);
221 void output_static_2(void)
223 output_static_safe(StaticFilemappings[2]);
225 void output_static_3(void)
227 output_static_safe(StaticFilemappings[3]);
231 ServerStartModule_STATIC
234 StaticFilemappings[0] = NewHash(1, NULL);
235 StaticFilemappings[1] = NewHash(1, NULL);
236 StaticFilemappings[2] = NewHash(1, NULL);
237 StaticFilemappings[3] = NewHash(1, NULL);
240 ServerShutdownModule_STATIC
243 DeleteHash(&StaticFilemappings[0]);
244 DeleteHash(&StaticFilemappings[1]);
245 DeleteHash(&StaticFilemappings[2]);
246 DeleteHash(&StaticFilemappings[3]);
254 LoadStaticDir(static_dirs[0], StaticFilemappings[0], "");
255 LoadStaticDir(static_dirs[1], StaticFilemappings[1], "");
256 LoadStaticDir(static_dirs[2], StaticFilemappings[2], "");
257 LoadStaticDir(static_dirs[3], StaticFilemappings[3], "");
259 WebcitAddUrlHandler(HKEY("robots.txt"), output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
260 WebcitAddUrlHandler(HKEY("favicon.ico"), output_flat_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
261 WebcitAddUrlHandler(HKEY("static"), output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
262 WebcitAddUrlHandler(HKEY("static.local"), output_static_1, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
263 WebcitAddUrlHandler(HKEY("tinymce"), output_static_2, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);