2 * parse urlparts and post data
4 * Copyright (c) 1996-2012 by the citadel.org team
6 * This program is open source software. You can redistribute it and/or
7 * modify it under the terms of the GNU General Public License, version 3.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
22 #include "webserver.h"
24 void free_url(void *U)
26 urlcontent *u = (urlcontent*) U;
27 FreeStrBuf(&u->url_data);
32 * Extract variables from the URL.
34 void ParseURLParams(StrBuf *url)
36 const char *aptr, *bptr, *eptr, *up;
41 if (WCC->Hdr->urlstrings == NULL)
42 WCC->Hdr->urlstrings = NewHash(1, NULL);
43 eptr = ChrPtr(url) + StrLength(url);
45 while ((up < eptr) && (!IsEmptyStr(up))) {
47 while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '='))
54 while ((bptr < eptr) && (*bptr != '\0')
55 && (*bptr != '&') && (*bptr != '?') && (*bptr != ' ')) {
58 keylen = aptr - up - 1; /* -1 -> '=' */
59 if(keylen > sizeof(u->url_key)) {
60 syslog(1, "URLkey to long! [%s]", up);
64 u = (urlcontent *) malloc(sizeof(urlcontent));
65 memcpy(u->url_key, up, keylen);
66 u->url_key[keylen] = '\0';
68 syslog(1, "URLkey to long! [%s]", up);
73 if (strncmp(u->url_key, "__", 2) != 0)
75 Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
77 u->url_data = NewStrBufPlain(aptr, len);
78 StrBufUnescape(u->url_data, 1);
79 #ifdef DEBUG_URLSTRINGS
80 syslog(9, "%s = [%d] %s\n",
82 StrLength(u->url_data),
88 u->url_data = NewStrBufPlain(aptr, len);
89 StrBufUnescape(u->url_data, 1);
90 syslog(1, "REJECTED because of __ is internal only: %s = [%d] %s\n",
92 StrLength(u->url_data),
103 * free urlstring memory
107 DeleteHash(&WC->Hdr->urlstrings);
111 * Diagnostic function to display the contents of all variables
123 Cursor = GetNewHashPos (WCC->Hdr->urlstrings, 0);
124 while (GetNextHashPos(WCC->Hdr->urlstrings, Cursor, &HKLen, &HKey, &U)) {
126 wc_printf("%38s = %s\n", u->url_key, ChrPtr(u->url_data));
131 * Return the value of a variable supplied to the current web page (from the url or a form)
134 const char *XBstr(const char *key, size_t keylen, size_t *len)
138 if ((WC->Hdr->urlstrings != NULL) &&
139 GetHash(WC->Hdr->urlstrings, key, keylen, &U)) {
140 *len = StrLength(((urlcontent *)U)->url_data);
141 return ChrPtr(((urlcontent *)U)->url_data);
149 const char *XBSTR(const char *key, size_t *len)
153 if ((WC->Hdr->urlstrings != NULL) &&
154 GetHash(WC->Hdr->urlstrings, key, strlen (key), &U)){
155 *len = StrLength(((urlcontent *)U)->url_data);
156 return ChrPtr(((urlcontent *)U)->url_data);
165 const char *BSTR(const char *key)
169 if ((WC->Hdr->urlstrings != NULL) &&
170 GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
171 return ChrPtr(((urlcontent *)U)->url_data);
176 const char *Bstr(const char *key, size_t keylen)
180 if ((WC->Hdr->urlstrings != NULL) &&
181 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
182 return ChrPtr(((urlcontent *)U)->url_data);
187 const StrBuf *SBSTR(const char *key)
191 if ((WC->Hdr->urlstrings != NULL) &&
192 GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
193 return ((urlcontent *)U)->url_data;
198 const StrBuf *SBstr(const char *key, size_t keylen)
202 if ((WC->Hdr->urlstrings != NULL) &&
203 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
204 return ((urlcontent *)U)->url_data;
209 long LBstr(const char *key, size_t keylen)
213 if ((WC->Hdr->urlstrings != NULL) &&
214 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
215 return StrTol(((urlcontent *)U)->url_data);
220 long LBSTR(const char *key)
224 if ((WC->Hdr->urlstrings != NULL) &&
225 GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
226 return StrTol(((urlcontent *)U)->url_data);
231 int IBstr(const char *key, size_t keylen)
235 if ((WC->Hdr->urlstrings != NULL) &&
236 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
237 return StrTol(((urlcontent *)U)->url_data);
242 int IBSTR(const char *key)
246 if ((WC->Hdr->urlstrings != NULL) &&
247 GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
248 return StrToi(((urlcontent *)U)->url_data);
253 int HaveBstr(const char *key, size_t keylen)
257 if ((WC->Hdr->urlstrings != NULL) &&
258 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
259 return (StrLength(((urlcontent *)U)->url_data) != 0);
264 int HAVEBSTR(const char *key)
268 if ((WC->Hdr->urlstrings != NULL) &&
269 GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
270 return (StrLength(((urlcontent *)U)->url_data) != 0);
276 int YesBstr(const char *key, size_t keylen)
280 if ((WC->Hdr->urlstrings != NULL) &&
281 GetHash(WC->Hdr->urlstrings, key, keylen, &U))
282 return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
287 int YESBSTR(const char *key)
291 if ((WC->Hdr->urlstrings != NULL) &&
292 GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
293 return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
302 * This function is called by the MIME parser to handle data uploaded by
303 * the browser. Form data, uploaded files, and the data from HTTP PUT
304 * operations (such as those found in GroupDAV) all arrive this way.
306 * name Name of the item being uploaded
307 * filename Filename of the item being uploaded
308 * partnum MIME part identifier (not needed)
309 * disp MIME content disposition (not needed)
310 * content The actual data
311 * cbtype MIME content-type
312 * cbcharset Character set
313 * length Content length
314 * encoding MIME encoding type (not needed)
315 * cbid Content ID (not needed)
316 * userdata Not used here
318 void upload_handler(char *name, char *filename, char *partnum, char *disp,
319 void *content, char *cbtype, char *cbcharset,
320 size_t length, char *encoding, char *cbid, void *userdata)
326 #ifdef DEBUG_URLSTRINGS
327 syslog(9, "upload_handler() name=%s, type=%s, len=%d", name, cbtype, length);
329 if (WCC->Hdr->urlstrings == NULL)
330 WCC->Hdr->urlstrings = NewHash(1, NULL);
333 if ( (length > 0) && (IsEmptyStr(cbtype)) ) {
334 u = (urlcontent *) malloc(sizeof(urlcontent));
336 keylen = safestrncpy(u->url_key, name, sizeof(u->url_key));
337 u->url_data = NewStrBufPlain(content, length);
339 if (strncmp(u->url_key, "__", 2) != 0)
341 Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
344 syslog(1, "REJECTED because of __ is internal only: %s = [%d] %s\n",
346 StrLength(u->url_data),
347 ChrPtr(u->url_data));
351 #ifdef DEBUG_URLSTRINGS
352 syslog(9, "Key: <%s> len: [%d] Data: <%s>",
354 StrLength(u->url_data),
355 ChrPtr(u->url_data));
360 if ( (length > 0) && (!IsEmptyStr(cbtype)) ) {
361 WCC->upload = NewStrBufPlain(content, length);
362 WCC->upload_length = length;
363 WCC->upload_filename = NewStrBufPlain(filename, -1);
364 safestrncpy(WCC->upload_content_type, cbtype, sizeof(WC->upload_content_type));
365 #ifdef DEBUG_URLSTRINGS
366 syslog(9, "File: <%s> len: [%ld]", filename, length);
375 void PutBstr(const char *key, long keylen, StrBuf *Value)
379 if(keylen > sizeof(u->url_key)) {
380 syslog(1, "URLkey to long! [%s]", key);
384 u = (urlcontent*)malloc(sizeof(urlcontent));
385 memcpy(u->url_key, key, keylen + 1);
387 Put(WC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
392 int ConditionalBstr(StrBuf *Target, WCTemplputParams *TP)
394 if(TP->Tokens->nParameters == 3)
395 return HaveBstr(TKEY(2));
397 if (IS_NUMBER(TP->Tokens->Params[3]->Type))
399 return LBstr(TKEY(2)) ==
400 GetTemplateTokenNumber(Target,
409 GetTemplateTokenString (Target, TP, 3, &pch, &len);
410 return strcmp(Bstr(TKEY(2)), pch) == 0;
415 void tmplput_bstr(StrBuf *Target, WCTemplputParams *TP)
417 const StrBuf *Buf = SBstr(TKEY(0));
419 StrBufAppendTemplate(Target, TP, Buf, 1);
423 void tmplput_bstrforward(StrBuf *Target, WCTemplputParams *TP)
425 const StrBuf *Buf = SBstr(TKEY(0));
427 StrBufAppendBufPlain(Target, HKEY("?"), 0);
428 StrBufAppendBufPlain(Target, TKEY(0), 0);
429 StrBufAppendBufPlain(Target, HKEY("="), 0);
430 StrBufAppendTemplate(Target, TP, Buf, 1);
434 void diagnostics(void)
436 output_headers(1, 1, 1, 0, 0, 0);
437 wc_printf("Session: %d<hr />\n", WC->wc_session);
438 wc_printf("Command: <br><PRE>\n");
440 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment1, 0, 0);
442 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment12 0, 0);
444 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment3, 0, 0);
446 wc_printf("</PRE><hr />\n");
447 wc_printf("Variables: <br><PRE>\n");
449 wc_printf("</PRE><hr />\n");
454 void tmplput_url_part(StrBuf *Target, WCTemplputParams *TP)
457 StrBuf *UrlBuf = NULL;
463 n = GetTemplateTokenNumber(Target, TP, 0, 0);
465 if (WCC->Hdr->HR.Handler != NULL)
466 UrlBuf = Name = WCC->Hdr->HR.Handler->Name;
469 UrlBuf = NewStrBuf();
470 StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 0, '/');
473 UrlBuf = NewStrBuf();
474 StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 1, '/');
477 if (UrlBuf == NULL) {
478 LogTemplateError(Target, "urlbuf", ERR_PARM1, TP, "not set.");
480 StrBufAppendTemplate(Target, TP, UrlBuf, 2);
481 if (Name == NULL) FreeStrBuf(&UrlBuf);
487 InitModule_PARAMHANDLING
490 WebcitAddUrlHandler(HKEY("diagnostics"), "", 0, diagnostics, NEED_URL);
492 RegisterConditional(HKEY("COND:BSTR"), 1, ConditionalBstr, CTX_NONE);
493 RegisterNamespace("BSTR", 1, 2, tmplput_bstr, NULL, CTX_NONE);
494 RegisterNamespace("BSTR:FORWARD", 1, 2, tmplput_bstrforward, NULL, CTX_NONE);
495 RegisterNamespace("URLPART", 1, 2, tmplput_url_part, NULL, CTX_NONE);
500 SessionAttachModule_PARAMHANDLING
503 sess->Hdr->urlstrings = NewHash(1,NULL);
507 SessionDetachModule_PARAMHANDLING
510 DeleteHash(&sess->Hdr->urlstrings);
511 FreeStrBuf(&sess->upload_filename);