From: Wilfried Göesgens Date: Sun, 17 May 2009 11:47:09 +0000 (+0000) Subject: * re-create static support; we now safe us from ..'ers by just looking up the filenam... X-Git-Tag: v7.86~1164 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=f573ffd76f7b76fe677cff1ba60e17c6b9eddbec * re-create static support; we now safe us from ..'ers by just looking up the filename in some pre-stored hash. --- diff --git a/webcit/Makefile.in b/webcit/Makefile.in index 5286d4e62..203281914 100644 --- a/webcit/Makefile.in +++ b/webcit/Makefile.in @@ -53,7 +53,7 @@ webcit: webserver.o context_loop.o ical_dezonify.o \ groupdav_delete.o groupdav_put.o http_datestring.o setup_wizard.o \ downloads.o addressbook_popup.o pushemail.o sysdep.o openid.o \ decode.o modules_init.o paramhandling.o utils.o \ - ical_maps.o ical_subst.o \ + ical_maps.o ical_subst.o static.o \ $(LIBOBJS) $(CC) $(LDFLAGS) $(LIBOBJS) $(LIBS) \ webserver.o context_loop.o cookie_conversion.o \ @@ -67,7 +67,7 @@ webcit: webserver.o context_loop.o ical_dezonify.o \ groupdav_options.o autocompletion.o tabs.o smtpqueue.o sieve.o \ groupdav_put.o http_datestring.o setup_wizard.o fmt_date.o modules_init.o \ gettext.o downloads.o addressbook_popup.o pushemail.o sysdep.o decode.o \ - paramhandling.o utils.o ical_maps.o ical_subst.o \ + paramhandling.o utils.o ical_maps.o ical_subst.o static.o \ -o webcit \ $(LIBS) diff --git a/webcit/auth.c b/webcit/auth.c index be1246527..d182b4023 100644 --- a/webcit/auth.c +++ b/webcit/auth.c @@ -62,6 +62,7 @@ int ReEstablish_Session(void) } } FreeStrBuf(&Buf); + return 0; } diff --git a/webcit/downloads.c b/webcit/downloads.c index e00161e15..b0e7cace3 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -235,7 +235,7 @@ void display_mime_icon(void) snprintf (FileBuf, SIZ, "%s%s", static_dirs[0], "/diskette_24x.gif"); else snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName); - //// TODO! output_static(FileBuf); + output_static(FileBuf); } void download_file(void) diff --git a/webcit/static.c b/webcit/static.c new file mode 100644 index 000000000..e12a10b29 --- /dev/null +++ b/webcit/static.c @@ -0,0 +1,338 @@ +/* + * $Id: webcit.c 7459 2009-05-17 08:34:33Z dothebart $ + * + * This is the main transaction loop of the web service. It maintains a + * persistent session to the Citadel server, handling HTTP WebCit requests as + * they arrive and presenting a user interface. + */ +#include +#include +#include +#include + +#include +#include +#include + +#include "webcit.h" +#include "webserver.h" + + +HashList *StaticFilemappings[4] = {NULL, NULL, NULL, NULL}; + + +/* + for ( a = 0; a < 9; ++a) + { + extract_token(index[a], ChrPtr(ReqLine), a + 1, '/', sizes[a]); + if (strstr(index[a], "?")) *strstr(index[a], "?") = 0; + if (strstr(index[a], "&")) *strstr(index[a], "&") = 0; + if (strstr(index[a], " ")) *strstr(index[a], " ") = 0; + if ((index[a][0] == '.') && (index[a][1] == '.')) + nBackDots++; + if (index[a][0] == '\0') + nEmpty++; + } +*/ + +/* TODO: staticdata +{ + + + /** Figure out the action * / + index[0] = action; + sizes[0] = sizeof action; + for (a=1; a<9; a++) + { + index[a] = arg[a-1]; + sizes[a] = sizeof arg[a-1]; + } + nBackDots = 0; + nEmpty = 0; + + + /* Static content can be sent without connecting to Citadel. * / + is_static = 0; + for (a=0; aWBuf, &fd, 1, bytes, &Err) < 0) + { + if (fd > 0) close(fd); + lprintf(9, "output_static('%s') -- FREAD FAILED (%s) --\n", what, strerror(errno)); + hprintf("HTTP/1.1 500 internal server error \r\n"); + hprintf("Content-Type: text/plain\r\n"); + end_burst(); + return; + } + + + close(fd); +#ifndef TECH_PREVIEW + lprintf(9, "output_static('%s') %s\n", what, content_type); +#endif + http_transmit_thing(content_type, 1); + } + if (yesbstr("force_close_session")) { + end_webcit_session(); + } +} + + /* TODO: integrate this into the static startup logic + + * While we're at it, gracefully handle requests for the + * robots.txt and favicon.ico files. + * / + if ((StrLength(ReqLine) >= 11) && + !strncasecmp(ChrPtr(ReqLine), "/robots.txt", 11)) { + StrBufPlain(ReqLine, + HKEY("/static/robots.txt" + "?force_close_session=yes HTTP/1.1")); + Hdr.eReqType = eGET; + } + else if ((StrLength(ReqLine) >= 11) && + !strncasecmp(ChrPtr(ReqLine), "/favicon.ico", 12)) { + StrBufPlain(ReqLine, HKEY("/static/favicon.ico")); + Hdr.eReqType = eGET; + } + +*/ + + + + +int LoadStaticDir(const char *DirName, HashList *DirList, const char *RelDir) +{ + char dirname[PATH_MAX]; + char reldir[PATH_MAX]; + StrBuf *FileName; + StrBuf *Tag; + StrBuf *Dir; + StrBuf *WebDir; + StrBuf *OneWebName; + DIR *filedir = NULL; + struct dirent d; + struct dirent *filedir_entry; + int d_namelen; + int d_without_ext; + + Dir = NewStrBufPlain(DirName, -1); + WebDir = NewStrBufPlain(RelDir, -1); + OneWebName = NewStrBuf(); + filedir = opendir (DirName); + if (filedir == NULL) { + FreeStrBuf(&Dir); + return 0; + } + + FileName = NewStrBuf(); + Tag = NewStrBuf(); + while ((readdir_r(filedir, &d, &filedir_entry) == 0) && + (filedir_entry != NULL)) + { + char *PStart; +#ifdef _DIRENT_HAVE_D_NAMELEN + d_namelen = filedir_entry->d_namelen; +#else + d_namelen = strlen(filedir_entry->d_name); +#endif + d_without_ext = d_namelen; + + if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~') + continue; /* Ignore backup files... */ + + if ((d_namelen == 1) && + (filedir_entry->d_name[0] == '.')) + continue; + + if ((d_namelen == 2) && + (filedir_entry->d_name[0] == '.') && + (filedir_entry->d_name[1] == '.')) + continue; + + switch (filedir_entry->d_type) + { + case DT_DIR: + /* Skip directories we are not interested in... */ + if ((strcmp(filedir_entry->d_name, ".svn") == 0) || + (strcmp(filedir_entry->d_name, "t") == 0)) + break; + snprintf(dirname, PATH_MAX, "%s/%s", + DirName, filedir_entry->d_name); + snprintf(reldir, PATH_MAX, "%s/%s", + RelDir, filedir_entry->d_name); + LoadStaticDir(dirname, DirList, reldir); + break; + case DT_LNK: /* TODO: check whether its a file or a directory */ + case DT_REG: + PStart = filedir_entry->d_name; + FileName = NewStrBufDup(Dir); + if (ChrPtr(FileName) [ StrLength(FileName) - 1] != '/') + StrBufAppendBufPlain(FileName, "/", 1, 0); + StrBufAppendBufPlain(FileName, filedir_entry->d_name, d_namelen, 0); + + FlushStrBuf(OneWebName); + StrBufAppendBuf(OneWebName, WebDir, 0); + if ((StrLength(OneWebName) != 0) && + (ChrPtr(OneWebName) [ StrLength(OneWebName)] != '/')) + StrBufAppendBufPlain(OneWebName, "/", 1, 0); + StrBufAppendBufPlain(OneWebName, filedir_entry->d_name, d_namelen, 0); + + Put(DirList, SKEY(OneWebName), FileName, HFreeStrBuf); + printf("[%s | %s] \n", ChrPtr(OneWebName), ChrPtr(FileName)); + break; + default: + break; + } + + + } + closedir(filedir); + FreeStrBuf(&FileName); + FreeStrBuf(&Tag); + FreeStrBuf(&Dir); + FreeStrBuf(&OneWebName); + return 1; +} + + +void output_static_safe(HashList *DirList) +{ + wcsession *WCC = WC; + void *vFile; + StrBuf *File; + + if (GetHash(DirList, SKEY(WCC->Hdr->ReqLine), &vFile) && + (vFile != NULL)) + { + File = (StrBuf*) vFile; + output_static(ChrPtr(vFile)); + } + else { +///TODO: detect image & output blank image + } +} +void output_static_0(void) +{ + output_static_safe(StaticFilemappings[0]); +} +void output_static_1(void) +{ + output_static_safe(StaticFilemappings[1]); +} +void output_static_2(void) +{ + output_static_safe(StaticFilemappings[2]); +} +void output_static_3(void) +{ + output_static_safe(StaticFilemappings[3]); +} + +void +ServerStartModule_STATIC +(void) +{ + StaticFilemappings[0] = NewHash(1, NULL); + StaticFilemappings[1] = NewHash(1, NULL); + StaticFilemappings[2] = NewHash(1, NULL); + StaticFilemappings[3] = NewHash(1, NULL); +} +void +ServerShutdownModule_STATIC +(void) +{ + DeleteHash(&StaticFilemappings[0]); + DeleteHash(&StaticFilemappings[1]); + DeleteHash(&StaticFilemappings[2]); + DeleteHash(&StaticFilemappings[3]); +} + + +void +InitModule_STATIC +(void) +{ + LoadStaticDir(static_dirs[0], StaticFilemappings[0], ""); + LoadStaticDir(static_dirs[1], StaticFilemappings[1], ""); + LoadStaticDir(static_dirs[2], StaticFilemappings[2], ""); + LoadStaticDir(static_dirs[3], StaticFilemappings[3], ""); + + WebcitAddUrlHandler(HKEY("robots.txt"), output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); + WebcitAddUrlHandler(HKEY("favicon.ico"), output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); + WebcitAddUrlHandler(HKEY("static"), output_static_0, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); + WebcitAddUrlHandler(HKEY("static.local"), output_static_1, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); + WebcitAddUrlHandler(HKEY("tinymce"), output_static_2, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); + + +} diff --git a/webcit/webcit.c b/webcit/webcit.c index e14fb312b..51c7ac73d 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -289,64 +289,6 @@ void print_menu_box(char* Title, char *Class, int nLines, ...) } -/* - * dump out static pages from disk - */ -void output_static(void) -{ - int fd; - struct stat statbuf; - off_t bytes; - off_t count = 0; - const char *content_type; - int len; - const char *Err; - char what[] = "TODO"; - fd = open(what, O_RDONLY); - if (fd <= 0) { - lprintf(9, "output_static('%s') -- NOT FOUND --\n", what); - hprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); - hprintf("Content-Type: text/plain\r\n"); - wprintf("Cannot open %s: %s\r\n", what, strerror(errno)); - end_burst(); - } else { - len = strlen (what); - content_type = GuessMimeByFilename(what, len); - - if (fstat(fd, &statbuf) == -1) { - lprintf(9, "output_static('%s') -- FSTAT FAILED --\n", what); - hprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); - hprintf("Content-Type: text/plain\r\n"); - wprintf("Cannot fstat %s: %s\n", what, strerror(errno)); - end_burst(); - return; - } - - count = 0; - bytes = statbuf.st_size; - - if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0) - { - if (fd > 0) close(fd); - lprintf(9, "output_static('%s') -- FREAD FAILED (%s) --\n", what, strerror(errno)); - hprintf("HTTP/1.1 500 internal server error \r\n"); - hprintf("Content-Type: text/plain\r\n"); - end_burst(); - return; - } - - - close(fd); -#ifndef TECH_PREVIEW - lprintf(9, "output_static('%s') %s\n", what, content_type); -#endif - http_transmit_thing(content_type, 1); - } - if (yesbstr("force_close_session")) { - end_webcit_session(); - } -} - /* * Convenience functions to display a page containing only a string @@ -452,45 +394,6 @@ void do_404(void) wprintf("Not found\r\n"); end_burst(); } -/* TODO: staticdata -{ - /* Static content can be sent without connecting to Citadel. * / - is_static = 0; - for (a=0; aHdr->nWildfireHeaders = 0; if (WCC->Hdr->Handler != NULL) Flags = WCC->Hdr->Handler->Flags; /* so we can temporarily add our own... */ - /** Figure out the action * / - index[0] = action; - sizes[0] = sizeof action; - for (a=1; a<9; a++) - { - index[a] = arg[a-1]; - sizes[a] = sizeof arg[a-1]; - } - nBackDots = 0; - nEmpty = 0; -/* - for ( a = 0; a < 9; ++a) - { - extract_token(index[a], ChrPtr(ReqLine), a + 1, '/', sizes[a]); - if (strstr(index[a], "?")) *strstr(index[a], "?") = 0; - if (strstr(index[a], "&")) *strstr(index[a], "&") = 0; - if (strstr(index[a], " ")) *strstr(index[a], " ") = 0; - if ((index[a][0] == '.') && (index[a][1] == '.')) - nBackDots++; - if (index[a][0] == '\0') - nEmpty++; - } -*/ + if (WCC->Hdr->ContentLength > 0) { ReadPostData(); } @@ -768,22 +649,6 @@ void session_loop(void) display_login(NULL); } else { -/* - if((WCC->Hdr->Handler->Flags & NEED_URL)) { - if (WCC->UrlFragment1 == NULL) - WCC->UrlFragment1 = NewStrBuf(); - if (WCC->UrlFragment2 == NULL) - WCC->UrlFragment2 = NewStrBuf(); - if (WCC->UrlFragment3 == NULL) - WCC->UrlFragment3 = NewStrBuf(); - if (WCC->UrlFragment4 == NULL) - WCC->UrlFragment4 = NewStrBuf(); - StrBufPlain(WCC->UrlFragment1, index[0], -1); - StrBufPlain(WCC->UrlFragment2, index[1], -1); - StrBufPlain(WCC->UrlFragment3, index[2], -1); - StrBufPlain(WCC->UrlFragment4, index[3], -1); - } -*/ if ((WCC->Hdr->Handler->Flags & AJAX) != 0) begin_ajax_response(); WCC->Hdr->Handler->F(); @@ -866,25 +731,6 @@ void tmplput_csslocal(StrBuf *Target, WCTemplputParams *TP) extern char static_local_dir[PATH_MAX]; - /* TODO: integrate this into the static startup logic - - * While we're at it, gracefully handle requests for the - * robots.txt and favicon.ico files. - * / - if ((StrLength(ReqLine) >= 11) && - !strncasecmp(ChrPtr(ReqLine), "/robots.txt", 11)) { - StrBufPlain(ReqLine, - HKEY("/static/robots.txt" - "?force_close_session=yes HTTP/1.1")); - Hdr.eReqType = eGET; - } - else if ((StrLength(ReqLine) >= 11) && - !strncasecmp(ChrPtr(ReqLine), "/favicon.ico", 12)) { - StrBufPlain(ReqLine, HKEY("/static/favicon.ico")); - Hdr.eReqType = eGET; - } - -*/ void InitModule_WEBCIT (void) @@ -893,11 +739,6 @@ InitModule_WEBCIT WebcitAddUrlHandler(HKEY("404"), do_404, ANONYMOUS|COOKIEUNNEEDED); WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); - WebcitAddUrlHandler(HKEY("robots.txt"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); - WebcitAddUrlHandler(HKEY("favicon.ico"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); - WebcitAddUrlHandler(HKEY("static"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); - WebcitAddUrlHandler(HKEY("static.local"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); - WebcitAddUrlHandler(HKEY("tinymce"), output_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC); WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS); WebcitAddUrlHandler(HKEY("do_template"), url_do_template, ANONYMOUS); @@ -973,12 +814,6 @@ SessionDestroyModule_WEBCIT { FreeStrBuf(&sess->WBuf); FreeStrBuf(&sess->HBuf); - /* - FreeStrBuf(&sess->UrlFragment1); - FreeStrBuf(&sess->UrlFragment2); - FreeStrBuf(&sess->UrlFragment3); - FreeStrBuf(&sess->UrlFragment4); - */ FreeStrBuf(&sess->ImportantMsg); } diff --git a/webcit/webcit.h b/webcit/webcit.h index 6a2b13589..008ccfdaa 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -435,10 +435,6 @@ typedef struct _ParsedHttpHdrs { StrBuf *browser_host; StrBuf *user_agent; - StrBuf *UrlFragment1; /**< first urlfragment, if NEED_URL is specified by the handler*/ - StrBuf *UrlFragment2; /**< second urlfragment, if NEED_URL is specified by the handler*/ - StrBuf *UrlFragment3; /**< third urlfragment, if NEED_URL is specified by the handler*/ - StrBuf *UrlFragment4; /**< fourth urlfragment, if NEED_URL is specified by the handler*/ StrBuf *this_page; /**< URL of current page */ StrBuf *PlainArgs; /*TODO: freeme*/ HashList *urlstrings; /**< variables passed to webcit in a URL */ @@ -695,7 +691,7 @@ void output_headers( int do_httpheaders, void output_custom_content_header(const char *ctype); void wprintf(const char *format,...)__attribute__((__format__(__printf__,1,2))); void hprintf(const char *format,...)__attribute__((__format__(__printf__,1,2))); -void output_static(void); +void output_static(const char* What); void print_menu_box(char* Title, char *Class, int nLines, ...); long stresc(char *target, long tSize, char *strbuf, int nbsp, int nolinebreaks);