X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=ed2eefc54bb4670794e31eb0a197948d4b8f32d8;hb=b4ad306de9560ec731db113ed509a1172209c444;hp=ebaf0c82e1fc440a4c7faa8551197ef488c01cf7;hpb=2cd5cf763302ab3aeaff98e84cf2df7ee48a7272;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index ebaf0c82e..ed2eefc54 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -149,7 +149,10 @@ void addurls(StrBuf *url) up = bptr; ++up; #ifdef DEBUG_URLSTRINGS - lprintf(9, "%s = [%ld] %s\n", u->url_key, u->url_data_size, ChrPtr(u->url_data)); + lprintf(9, "%s = [%ld] %s\n", + u->url_key, + StrLength(u->url_data), + ChrPtr(u->url_data)); #endif } //free(buf); @@ -187,7 +190,7 @@ void dump_vars(void) * Return the value of a variable supplied to the current web page (from the url or a form) */ -const char *XBstr(char *key, size_t keylen, size_t *len) +const char *XBstr(const char *key, size_t keylen, size_t *len) { void *U; @@ -202,7 +205,7 @@ const char *XBstr(char *key, size_t keylen, size_t *len) } } -const char *XBSTR(char *key, size_t *len) +const char *XBSTR(const char *key, size_t *len) { void *U; @@ -218,7 +221,7 @@ const char *XBSTR(char *key, size_t *len) } -const char *BSTR(char *key) +const char *BSTR(const char *key) { void *U; @@ -229,7 +232,7 @@ const char *BSTR(char *key) return (""); } -const char *Bstr(char *key, size_t keylen) +const char *Bstr(const char *key, size_t keylen) { void *U; @@ -262,7 +265,7 @@ const StrBuf *SBstr(const char *key, size_t keylen) return NULL; } -long LBstr(char *key, size_t keylen) +long LBstr(const char *key, size_t keylen) { void *U; @@ -273,7 +276,7 @@ long LBstr(char *key, size_t keylen) return (0); } -long LBSTR(char *key) +long LBSTR(const char *key) { void *U; @@ -284,7 +287,7 @@ long LBSTR(char *key) return (0); } -int IBstr(char *key, size_t keylen) +int IBstr(const char *key, size_t keylen) { void *U; @@ -295,7 +298,7 @@ int IBstr(char *key, size_t keylen) return (0); } -int IBSTR(char *key) +int IBSTR(const char *key) { void *U; @@ -306,7 +309,7 @@ int IBSTR(char *key) return (0); } -int HaveBstr(char *key, size_t keylen) +int HaveBstr(const char *key, size_t keylen) { void *U; @@ -317,7 +320,7 @@ int HaveBstr(char *key, size_t keylen) return (0); } -int HAVEBSTR(char *key) +int HAVEBSTR(const char *key) { void *U; @@ -329,7 +332,7 @@ int HAVEBSTR(char *key) } -int YesBstr(char *key, size_t keylen) +int YesBstr(const char *key, size_t keylen) { void *U; @@ -340,7 +343,7 @@ int YesBstr(char *key, size_t keylen) return (0); } -int YESBSTR(char *key) +int YESBSTR(const char *key) { void *U; @@ -611,12 +614,14 @@ void jsescputs(char *strbuf) */ void msgescputs1( char *strbuf) { - StrBuf *OutBuf = NewStrBuf(); + StrBuf *OutBuf; if ((strbuf == NULL) || IsEmptyStr(strbuf)) return; + OutBuf = NewStrBuf(); StrMsgEscAppend(OutBuf, NULL, strbuf); StrEscAppend(WC->WBuf, OutBuf, NULL, 0, 0); + FreeStrBuf(&OutBuf); } /* @@ -762,6 +767,10 @@ void http_redirect(const char *whichpage) { void http_transmit_thing(const char *content_type, int is_static) { + lprintf(9, "http_transmit_thing(%s)%s\n", + content_type, + (is_static ? " (static)" : "") + ); output_headers(0, 0, 0, 0, 0, is_static); hprintf("Content-type: %s\r\n" @@ -1050,7 +1059,7 @@ void url_do_template(void) { const StrBuf *Tmpl = sbstr("template"); begin_burst(); output_headers(1, 0, 0, 0, 1, 0); - DoTemplate(ChrPtr(Tmpl), StrLength(Tmpl), NULL, NULL); + DoTemplate(ChrPtr(Tmpl), StrLength(Tmpl), NULL, NULL, 0); end_burst(); } @@ -1059,7 +1068,7 @@ void url_do_template(void) { /* * Offer to make any page the user's "start page." */ -void offer_start_page(void) { +void offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context, int ContextType) { wprintf("this_page); wprintf("\">"); @@ -1160,7 +1169,10 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, Put(WC->urlstrings, u->url_key, strlen(u->url_key), u, free_url); #ifdef DEBUG_URLSTRINGS - lprintf(9, "Key: <%s> len: [%ld] Data: <%s>\n", u->url_key, u->url_data_size, u->url_data); + lprintf(9, "Key: <%s> len: [%ld] Data: <%s>\n", + u->url_key, + StrLength(u->url_data), + ChrPtr(u->url_data)); #endif } @@ -1203,7 +1215,6 @@ void begin_ajax_response(void) { * print ajax response footer */ void end_ajax_response(void) { - ///hprintf("\r\n");///// todo: is this right? wDumpContent(0); } @@ -1276,6 +1287,7 @@ void seconds_since_last_gexp(void) wprintf("NO\n"); } else { + memset(buf, 5, 0); serv_puts("NOOP"); serv_getln(buf, sizeof buf); if (buf[3] == '*') { @@ -1310,22 +1322,21 @@ int is_mobile_ua(char *user_agent) { /* * Entry point for WebCit transaction */ -void session_loop(struct httprequest *req) +void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method, StrBuf *ReadBuf) { - char cmd[1024]; + const char *pch, *pchs, *pche; + void *vLine; char action[1024]; char arg[8][128]; size_t sizes[10]; char *index[10]; char buf[SIZ]; - char request_method[128]; - char pathname[1024]; - int a, b, nBackDots, nEmpty; + int a, nBackDots, nEmpty; int ContentLength = 0; - char ContentType[512]; - char *content = NULL; - char *content_end = NULL; - struct httprequest *hptr; + StrBuf *ContentType = NULL; + StrBuf *UrlLine = NULL; + StrBuf *content = NULL; + const char *content_end = NULL; char browser_host[256]; char user_agent[256]; int body_start = 0; @@ -1342,7 +1353,6 @@ void session_loop(struct httprequest *req) char c_httpauth_string[SIZ]; char c_httpauth_user[SIZ]; char c_httpauth_pass[SIZ]; - char cookie[SIZ]; struct wcsession *WCC; safestrncpy(c_username, "", sizeof c_username); @@ -1366,14 +1376,6 @@ void session_loop(struct httprequest *req) WCC->upload = NULL; WCC->is_mobile = 0; - hptr = req; - if (hptr == NULL) return; - - safestrncpy(cmd, hptr->line, sizeof cmd); - hptr = hptr->next; - extract_token(request_method, cmd, 0, ' ', sizeof request_method); - extract_token(pathname, cmd, 1, ' ', sizeof pathname); - /** Figure out the action */ index[0] = action; sizes[0] = sizeof action; @@ -1387,7 +1389,7 @@ void session_loop(struct httprequest *req) nEmpty = 0; for ( a = 0; a < 9; ++a) { - extract_token(index[a], pathname, a + 1, '/', sizes[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; @@ -1397,113 +1399,109 @@ void session_loop(struct httprequest *req) nEmpty++; } - while (hptr != NULL) { - safestrncpy(buf, hptr->line, sizeof buf); - /* lprintf(9, "HTTP HEADER: %s\n", buf); */ - hptr = hptr->next; - if (!strncasecmp(buf, "Cookie: webcit=", 15)) { - safestrncpy(cookie, &buf[15], sizeof cookie); - cookie_to_stuff(cookie, NULL, - c_username, sizeof c_username, - c_password, sizeof c_password, - c_roomname, sizeof c_roomname); - } - else if (!strncasecmp(buf, "Authorization: Basic ", 21)) { - CtdlDecodeBase64(c_httpauth_string, &buf[21], strlen(&buf[21])); - extract_token(c_httpauth_user, c_httpauth_string, 0, ':', sizeof c_httpauth_user); - extract_token(c_httpauth_pass, c_httpauth_string, 1, ':', sizeof c_httpauth_pass); - } - else if (!strncasecmp(buf, "Content-length: ", 16)) { - ContentLength = atoi(&buf[16]); - } - else if (!strncasecmp(buf, "Content-type: ", 14)) { - safestrncpy(ContentType, &buf[14], sizeof ContentType); - } - else if (!strncasecmp(buf, "User-agent: ", 12)) { - safestrncpy(user_agent, &buf[12], sizeof user_agent); - #ifdef TECH_PREVIEW - if (is_mobile_ua(&buf[12])) { - WCC->is_mobile = 1; - } - #endif - } - else if (!strncasecmp(buf, "X-Forwarded-Host: ", 18)) { - if (follow_xff) { - safestrncpy(WCC->http_host, &buf[18], sizeof WCC->http_host); - } + if (GetHash(HTTPHeaders, HKEY("COOKIE"), &vLine) && + (vLine != NULL)){ + cookie_to_stuff((StrBuf *)vLine, NULL, + c_username, sizeof c_username, + c_password, sizeof c_password, + c_roomname, sizeof c_roomname); + } + if (GetHash(HTTPHeaders, HKEY("AUTHORIZATION"), &vLine) && + (vLine!=NULL)) { + CtdlDecodeBase64(c_httpauth_string, ChrPtr((StrBuf*)vLine), StrLength((StrBuf*)vLine)); + extract_token(c_httpauth_user, c_httpauth_string, 0, ':', sizeof c_httpauth_user); + extract_token(c_httpauth_pass, c_httpauth_string, 1, ':', sizeof c_httpauth_pass); + } + if (GetHash(HTTPHeaders, HKEY("CONTENT-LENGTH"), &vLine) && + (vLine!=NULL)) { + ContentLength = StrToi((StrBuf*)vLine); + } + if (GetHash(HTTPHeaders, HKEY("CONTENT-TYPE"), &vLine) && + (vLine!=NULL)) { + ContentType = (StrBuf*)vLine; + } + if (GetHash(HTTPHeaders, HKEY("USER-AGENT"), &vLine) && + (vLine!=NULL)) { + safestrncpy(user_agent, ChrPtr((StrBuf*)vLine), sizeof user_agent); +#ifdef TECH_PREVIEW + if ((WCC->is_mobile < 0) && is_mobile_ua(&buf[12])) { + WCC->is_mobile = 1; } - else if (!strncasecmp(buf, "Host: ", 6)) { - if (IsEmptyStr(WCC->http_host)) { - safestrncpy(WCC->http_host, &buf[6], sizeof WCC->http_host); - } + else { + WCC->is_mobile = 0; } - else if (!strncasecmp(buf, "X-Forwarded-For: ", 17)) { - safestrncpy(browser_host, &buf[17], sizeof browser_host); - while (num_tokens(browser_host, ',') > 1) { - remove_token(browser_host, 0, ','); - } - striplt(browser_host); +#endif + } + if ((follow_xff) && + GetHash(HTTPHeaders, HKEY("X-FORWARDED-HOST"), &vLine) && + (vLine != NULL)) { + safestrncpy(WCC->http_host, &buf[18], sizeof WCC->http_host); + } + if (IsEmptyStr(WCC->http_host) && + GetHash(HTTPHeaders, HKEY("HOST"), &vLine) && + (vLine!=NULL)) { + safestrncpy(WCC->http_host, + ChrPtr((StrBuf*)vLine), + sizeof WCC->http_host); + + } + if (GetHash(HTTPHeaders, HKEY("X-FORWARDED-FOR"), &vLine) && + (vLine!=NULL)) { + safestrncpy(browser_host, + ChrPtr((StrBuf*) vLine), + sizeof browser_host); + while (num_tokens(browser_host, ',') > 1) { + remove_token(browser_host, 0, ','); } + striplt(browser_host); } if (ContentLength > 0) { - int BuffSize; - - BuffSize = ContentLength + SIZ; - content = malloc(BuffSize); - memset(content, 0, BuffSize); - snprintf(content, BuffSize, "Content-type: %s\n" + content = NewStrBuf(); + StrBufPrintf(content, "Content-type: %s\n" "Content-length: %d\n\n", - ContentType, ContentLength); + ChrPtr(ContentType), ContentLength); /* hprintf("Content-type: %s\n" "Content-length: %d\n\n", ContentType, ContentLength); */ - body_start = strlen(content); + body_start = StrLength(content); /** Read the entire input data at once. */ - client_read(WCC->http_sock, &content[body_start], ContentLength); - - if (!strncasecmp(ContentType, "application/x-www-form-urlencoded", 33)) { - StrBuf *Content; - - Content = _NewConstStrBuf(&content[body_start],ContentLength); - addurls(Content); - FreeStrBuf(&Content); - } else if (!strncasecmp(ContentType, "multipart", 9)) { - content_end = content + ContentLength + body_start; - mime_parser(content, content_end, *upload_handler, NULL, NULL, NULL, 0); + client_read(&WCC->http_sock, content, ReadBuf, ContentLength); + + if (!strncasecmp(ChrPtr(ContentType), "application/x-www-form-urlencoded", 33)) { + StrBufCutLeft(content, body_start); + addurls(content); + } else if (!strncasecmp(ChrPtr(ContentType), "multipart", 9)) { + content_end = ChrPtr(content) + ContentLength + body_start; + mime_parser(ChrPtr(content), content_end, *upload_handler, NULL, NULL, NULL, 0); } } else { content = NULL; } /* make a note of where we are in case the user wants to save it */ - safestrncpy(WCC->this_page, cmd, sizeof(WCC->this_page)); + safestrncpy(WCC->this_page, ChrPtr(ReqLine), sizeof(WCC->this_page)); remove_token(WCC->this_page, 2, ' '); remove_token(WCC->this_page, 0, ' '); /* If there are variables in the URL, we must grab them now */ - len = strlen(cmd); - for (a = 0; a < len; ++a) { - if ((cmd[a] == '?') || (cmd[a] == '&')) { - StrBuf *Params; - for (b = a; b < len; ++b) { - if (isspace(cmd[b])){ - cmd[b] = 0; - len = b - 1; - } - } - //cmd[len - a] = '\0'; - Params = _NewConstStrBuf(&cmd[a + 1], len - a); - addurls(Params); - FreeStrBuf(&Params); - cmd[a] = 0; - len = a - 1; + UrlLine = NewStrBufDup(ReqLine); + len = StrLength(UrlLine); + pch = pchs = ChrPtr(UrlLine); + pche = pchs + len; + while (pch < pche) { + if ((*pch == '?') || (*pch == '&')) { + StrBufCutLeft(UrlLine, pch - pchs + 1); + addurls(UrlLine); + break; } + pch ++; } + FreeStrBuf(&UrlLine); /* If it's a "force 404" situation then display the error and bail. */ if (!strcmp(action, "404")) { @@ -1516,7 +1514,7 @@ void session_loop(struct httprequest *req) /* Static content can be sent without connecting to Citadel. */ is_static = 0; - for (a=0; alogged_in) { WCC->killthis = 1; /* If not logged in, don't */ } /* keep the session active */ @@ -1679,9 +1679,10 @@ void session_loop(struct httprequest *req) * Automatically send requests with any method other than GET or * POST to the GroupDAV code as well. */ - if ((strcasecmp(request_method, "GET")) && (strcasecmp(request_method, "POST"))) { - groupdav_main(req, ContentType, /** do GroupDAV methods */ - ContentLength, content+body_start); + if ((strcasecmp(ChrPtr(request_method), "GET")) && (strcasecmp(ChrPtr(request_method), "POST"))) { + groupdav_main(HTTPHeaders, ReqLine, + request_method, ContentType, /** do GroupDAV methods */ + ContentLength, content, body_start); if (!WCC->logged_in) { WCC->killthis = 1; /** If not logged in, don't */ } /** keep the session active */ @@ -1764,7 +1765,7 @@ void session_loop(struct httprequest *req) SKIP_ALL_THIS_CRAP: fflush(stdout); if (content != NULL) { - free(content); + FreeStrBuf(&content); content = NULL; } free_urls(); @@ -1792,9 +1793,9 @@ void diagnostics(void) output_headers(1, 1, 1, 0, 0, 0); wprintf("Session: %d
\n", WC->wc_session); wprintf("Command:
\n");
-	escputs(WC->UrlFragment1);
+	StrEscPuts(WC->UrlFragment1);
 	wprintf("
\n"); - escputs(WC->UrlFragment2); + StrEscPuts(WC->UrlFragment2); wprintf("

\n"); wprintf("Variables:
\n");
 	dump_vars();
@@ -1815,7 +1816,7 @@ void download_mimepart(void) {
 }
 
 
-int ConditionalImportantMesage(WCTemplateToken *Tokens, void *Context)
+int ConditionalImportantMesage(WCTemplateToken *Tokens, void *Context, int ContextType)
 {
 	struct wcsession *WCC = WC;
 	if (WCC != NULL)
@@ -1824,7 +1825,7 @@ int ConditionalImportantMesage(WCTemplateToken *Tokens, void *Context)
 		return 0;
 }
 
-void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context)
+void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
 {
 	struct wcsession *WCC = WC;
 	
@@ -1834,9 +1835,22 @@ void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens
 	}
 }
 
-void tmplput_offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context)
+int ConditionalBstr(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+	if(Tokens->nParameters == 1)
+		return HaveBstr(Tokens->Params[0]->Start, 
+				Tokens->Params[0]->len);
+	else
+		return strcmp(Bstr(Tokens->Params[0]->Start, 
+				   Tokens->Params[0]->len),
+			      Tokens->Params[1]->Start) == 0;
+}
+
+void tmplput_bstr(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
 {
-	offer_start_page();
+	StrBufAppendBuf(Target, 
+			SBstr(Tokens->Params[0]->Start, 
+			      Tokens->Params[0]->len), 0);
 }
 
 void 
@@ -1853,7 +1867,10 @@ InitModule_WEBCIT
 	WebcitAddUrlHandler(HKEY("mimepart"), view_mimepart, NEED_URL);
 	WebcitAddUrlHandler(HKEY("mimepart_download"), download_mimepart, NEED_URL);
 	WebcitAddUrlHandler(HKEY("diagnostics"), diagnostics, NEED_URL);
-	RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage);
-	RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage);
-	RegisterNamespace("OFFERSTARTPAGE", 0, 0, tmplput_offer_start_page);
+
+	RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE);
+	RegisterConditional(HKEY("COND:BSTR"), 1, ConditionalBstr, CTX_NONE);
+	RegisterNamespace("BSTR", 1, 2, tmplput_bstr, CTX_NONE);
+	RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, CTX_NONE);
+	RegisterNamespace("OFFERSTARTPAGE", 0, 0, offer_start_page, CTX_NONE);
 }