Back to index

webcit  8.12-dfsg
paramhandling.c
Go to the documentation of this file.
00001 /*
00002  * parse urlparts and post data
00003  *
00004  * Copyright (c) 1996-2012 by the citadel.org team
00005  *
00006  * This program is open source software.  You can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License, version 3.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "webcit.h"
00016 #include "webserver.h"
00017 
00018 void free_url(void *U)
00019 {
00020        urlcontent *u = (urlcontent*) U;
00021        FreeStrBuf(&u->url_data);
00022        free(u);
00023 }
00024 
00025 /*
00026  * Extract variables from the URL.
00027  */
00028 void ParseURLParams(StrBuf *url)
00029 {
00030        const char *aptr, *bptr, *eptr, *up;
00031        int len, keylen;
00032        urlcontent *u;
00033        wcsession *WCC = WC;
00034 
00035        if (WCC->Hdr->urlstrings == NULL)
00036               WCC->Hdr->urlstrings = NewHash(1, NULL);
00037        eptr = ChrPtr(url) + StrLength(url);
00038        up = ChrPtr(url);
00039        while ((up < eptr) && (!IsEmptyStr(up))) {
00040               aptr = up;
00041               while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '='))
00042                      aptr++;
00043               if (*aptr != '=') {
00044                      return;
00045               }
00046               aptr++;
00047               bptr = aptr;
00048               while ((bptr < eptr) && (*bptr != '\0')
00049                     && (*bptr != '&') && (*bptr != '?') && (*bptr != ' ')) {
00050                      bptr++;
00051               }
00052               keylen = aptr - up - 1; /* -1 -> '=' */
00053               if(keylen > sizeof(u->url_key)) {
00054                      syslog(1, "URLkey to long! [%s]", up);
00055                      continue;
00056               }
00057 
00058               u = (urlcontent *) malloc(sizeof(urlcontent));
00059               memcpy(u->url_key, up, keylen);
00060               u->url_key[keylen] = '\0';
00061               if (keylen < 0) {
00062                      syslog(1, "URLkey to long! [%s]", up);
00063                      free(u);
00064                      continue;
00065               }
00066               
00067               if (strncmp(u->url_key, "__", 2) != 0)
00068               {
00069                      Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
00070                      len = bptr - aptr;
00071                      u->url_data = NewStrBufPlain(aptr, len);
00072                      StrBufUnescape(u->url_data, 1);
00073 #ifdef DEBUG_URLSTRINGS
00074                      syslog(9, "%s = [%d]  %s\n", 
00075                             u->url_key, 
00076                             StrLength(u->url_data), 
00077                             ChrPtr(u->url_data)); 
00078 #endif
00079               }
00080               else {
00081                      len = bptr - aptr;
00082                      u->url_data = NewStrBufPlain(aptr, len);
00083                      StrBufUnescape(u->url_data, 1);
00084                      syslog(1, "REJECTED because of __ is internal only: %s = [%d]  %s\n", 
00085                             u->url_key, 
00086                             StrLength(u->url_data), 
00087                             ChrPtr(u->url_data)); 
00088                      
00089                      free_url(u);
00090               }
00091               up = bptr;
00092               ++up;
00093        }
00094 }
00095 
00096 /*
00097  * free urlstring memory
00098  */
00099 void free_urls(void)
00100 {
00101        DeleteHash(&WC->Hdr->urlstrings);
00102 }
00103 
00104 /*
00105  * Diagnostic function to display the contents of all variables
00106  */
00107 
00108 void dump_vars(void)
00109 {
00110        wcsession *WCC = WC;
00111        urlcontent *u;
00112        void *U;
00113        long HKLen;
00114        const char *HKey;
00115        HashPos *Cursor;
00116        
00117        Cursor = GetNewHashPos (WCC->Hdr->urlstrings, 0);
00118        while (GetNextHashPos(WCC->Hdr->urlstrings, Cursor, &HKLen, &HKey, &U)) {
00119               u = (urlcontent*) U;
00120               wc_printf("%38s = %s\n", u->url_key, ChrPtr(u->url_data));
00121        }
00122 }
00123 
00124 /*
00125  * Return the value of a variable supplied to the current web page (from the url or a form)
00126  */
00127 
00128 const char *XBstr(const char *key, size_t keylen, size_t *len)
00129 {
00130        void *U;
00131 
00132        if ((WC->Hdr->urlstrings != NULL) && 
00133            GetHash(WC->Hdr->urlstrings, key, keylen, &U)) {
00134               *len = StrLength(((urlcontent *)U)->url_data);
00135               return ChrPtr(((urlcontent *)U)->url_data);
00136        }
00137        else {
00138               *len = 0;
00139               return ("");
00140        }
00141 }
00142 
00143 const char *XBSTR(const char *key, size_t *len)
00144 {
00145        void *U;
00146 
00147        if ((WC->Hdr->urlstrings != NULL) &&
00148            GetHash(WC->Hdr->urlstrings, key, strlen (key), &U)){
00149               *len = StrLength(((urlcontent *)U)->url_data);
00150               return ChrPtr(((urlcontent *)U)->url_data);
00151        }
00152        else {
00153               *len = 0;
00154               return ("");
00155        }
00156 }
00157 
00158 
00159 const char *BSTR(const char *key)
00160 {
00161        void *U;
00162 
00163        if ((WC->Hdr->urlstrings != NULL) &&
00164            GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
00165               return ChrPtr(((urlcontent *)U)->url_data);
00166        else   
00167               return ("");
00168 }
00169 
00170 const char *Bstr(const char *key, size_t keylen)
00171 {
00172        void *U;
00173 
00174        if ((WC->Hdr->urlstrings != NULL) && 
00175            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00176               return ChrPtr(((urlcontent *)U)->url_data);
00177        else   
00178               return ("");
00179 }
00180 
00181 const StrBuf *SBSTR(const char *key)
00182 {
00183        void *U;
00184 
00185        if ((WC->Hdr->urlstrings != NULL) &&
00186            GetHash(WC->Hdr->urlstrings, key, strlen (key), &U))
00187               return ((urlcontent *)U)->url_data;
00188        else   
00189               return NULL;
00190 }
00191 
00192 const StrBuf *SBstr(const char *key, size_t keylen)
00193 {
00194        void *U;
00195 
00196        if ((WC->Hdr->urlstrings != NULL) && 
00197            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00198               return ((urlcontent *)U)->url_data;
00199        else   
00200               return NULL;
00201 }
00202 
00203 long LBstr(const char *key, size_t keylen)
00204 {
00205        void *U;
00206 
00207        if ((WC->Hdr->urlstrings != NULL) && 
00208            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00209               return StrTol(((urlcontent *)U)->url_data);
00210        else   
00211               return (0);
00212 }
00213 
00214 long LBSTR(const char *key)
00215 {
00216        void *U;
00217 
00218        if ((WC->Hdr->urlstrings != NULL) && 
00219            GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
00220               return StrTol(((urlcontent *)U)->url_data);
00221        else   
00222               return (0);
00223 }
00224 
00225 int IBstr(const char *key, size_t keylen)
00226 {
00227        void *U;
00228 
00229        if ((WC->Hdr->urlstrings != NULL) && 
00230            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00231               return StrTol(((urlcontent *)U)->url_data);
00232        else   
00233               return (0);
00234 }
00235 
00236 int IBSTR(const char *key)
00237 {
00238        void *U;
00239 
00240        if ((WC->Hdr->urlstrings != NULL) && 
00241            GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
00242               return StrToi(((urlcontent *)U)->url_data);
00243        else   
00244               return (0);
00245 }
00246 
00247 int HaveBstr(const char *key, size_t keylen)
00248 {
00249        void *U;
00250 
00251        if ((WC->Hdr->urlstrings != NULL) && 
00252            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00253               return (StrLength(((urlcontent *)U)->url_data) != 0);
00254        else   
00255               return (0);
00256 }
00257 
00258 int HAVEBSTR(const char *key)
00259 {
00260        void *U;
00261 
00262        if ((WC->Hdr->urlstrings != NULL) && 
00263            GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
00264               return (StrLength(((urlcontent *)U)->url_data) != 0);
00265        else   
00266               return (0);
00267 }
00268 
00269 
00270 int YesBstr(const char *key, size_t keylen)
00271 {
00272        void *U;
00273 
00274        if ((WC->Hdr->urlstrings != NULL) && 
00275            GetHash(WC->Hdr->urlstrings, key, keylen, &U))
00276               return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
00277        else   
00278               return (0);
00279 }
00280 
00281 int YESBSTR(const char *key)
00282 {
00283        void *U;
00284 
00285        if ((WC->Hdr->urlstrings != NULL) && 
00286            GetHash(WC->Hdr->urlstrings, key, strlen(key), &U))
00287               return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0;
00288        else   
00289               return (0);
00290 }
00291 
00292 
00293 
00294 
00295 /*
00296  * This function is called by the MIME parser to handle data uploaded by
00297  * the browser.  Form data, uploaded files, and the data from HTTP PUT
00298  * operations (such as those found in GroupDAV) all arrive this way.
00299  *
00300  * name              Name of the item being uploaded
00301  * filename   Filename of the item being uploaded
00302  * partnum    MIME part identifier (not needed)
00303  * disp              MIME content disposition (not needed)
00304  * content    The actual data
00305  * cbtype     MIME content-type
00306  * cbcharset  Character set
00307  * length     Content length
00308  * encoding   MIME encoding type (not needed)
00309  * cbid              Content ID (not needed)
00310  * userdata   Not used here
00311  */
00312 void upload_handler(char *name, char *filename, char *partnum, char *disp,
00313                      void *content, char *cbtype, char *cbcharset,
00314                      size_t length, char *encoding, char *cbid, void *userdata)
00315 {
00316        wcsession *WCC = WC;
00317        urlcontent *u;
00318        long keylen;
00319 
00320 #ifdef DEBUG_URLSTRINGS
00321        syslog(9, "upload_handler() name=%s, type=%s, len=%d", name, cbtype, length);
00322 #endif
00323        if (WCC->Hdr->urlstrings == NULL)
00324               WCC->Hdr->urlstrings = NewHash(1, NULL);
00325 
00326        /* Form fields */
00327        if ( (length > 0) && (IsEmptyStr(cbtype)) ) {
00328               u = (urlcontent *) malloc(sizeof(urlcontent));
00329               
00330               keylen = safestrncpy(u->url_key, name, sizeof(u->url_key));
00331               u->url_data = NewStrBufPlain(content, length);
00332               
00333               if (strncmp(u->url_key, "__", 2) != 0)
00334               {
00335                      Put(WCC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
00336               }
00337               else {
00338                      syslog(1, "REJECTED because of __ is internal only: %s = [%d]  %s\n", 
00339                             u->url_key, 
00340                             StrLength(u->url_data), 
00341                             ChrPtr(u->url_data)); 
00342                      
00343                      free_url(u);
00344               }
00345 #ifdef DEBUG_URLSTRINGS
00346               syslog(9, "Key: <%s> len: [%d] Data: <%s>", 
00347                      u->url_key, 
00348                      StrLength(u->url_data), 
00349                      ChrPtr(u->url_data));
00350 #endif
00351        }
00352 
00353        /* Uploaded files */
00354        if ( (length > 0) && (!IsEmptyStr(cbtype)) ) {
00355               WCC->upload = NewStrBufPlain(content, length);
00356               WCC->upload_length = length;
00357               WCC->upload_filename = NewStrBufPlain(filename, -1);
00358               safestrncpy(WCC->upload_content_type, cbtype, sizeof(WC->upload_content_type));
00359 #ifdef DEBUG_URLSTRINGS
00360               syslog(9, "File: <%s> len: [%ld]", filename, length);
00361 #endif
00362               
00363        }
00364 
00365 }
00366 
00367 
00368 
00369 void PutBstr(const char *key, long keylen, StrBuf *Value)
00370 {
00371        urlcontent *u;
00372 
00373        if(keylen > sizeof(u->url_key)) {
00374               syslog(1, "URLkey to long! [%s]", key);
00375               FreeStrBuf(&Value);
00376               return;
00377        }
00378        u = (urlcontent*)malloc(sizeof(urlcontent));
00379        memcpy(u->url_key, key, keylen + 1);
00380        u->url_data = Value;
00381        Put(WC->Hdr->urlstrings, u->url_key, keylen, u, free_url);
00382 }
00383 
00384 
00385 
00386 int ConditionalBstr(StrBuf *Target, WCTemplputParams *TP)
00387 {
00388        if(TP->Tokens->nParameters == 3)
00389               return HaveBstr(TKEY(2));
00390        else {
00391               if (IS_NUMBER(TP->Tokens->Params[3]->Type))
00392               {
00393                      return LBstr(TKEY(2)) == 
00394                             GetTemplateTokenNumber(Target, 
00395                                                  TP, 
00396                                                  3, 
00397                                                  0);
00398               }
00399               else {
00400                      const char *pch;
00401                      long len;
00402 
00403                      GetTemplateTokenString (Target, TP, 3, &pch, &len);
00404                      return strcmp(Bstr(TKEY(2)), pch) == 0;
00405               }
00406        }
00407 }
00408 
00409 void tmplput_bstr(StrBuf *Target, WCTemplputParams *TP)
00410 {
00411        const StrBuf *Buf = SBstr(TKEY(0));
00412        if (Buf != NULL)
00413               StrBufAppendTemplate(Target, TP, Buf, 1);
00414 }
00415 
00416 
00417 void tmplput_bstrforward(StrBuf *Target, WCTemplputParams *TP)
00418 {
00419        const StrBuf *Buf = SBstr(TKEY(0));
00420        if (Buf != NULL) {
00421               StrBufAppendBufPlain(Target, HKEY("?"), 0);             
00422               StrBufAppendBufPlain(Target, TKEY(0), 0);
00423               StrBufAppendBufPlain(Target, HKEY("="), 0);             
00424               StrBufAppendTemplate(Target, TP, Buf, 1);
00425        }
00426 }
00427 
00428 void diagnostics(void)
00429 {
00430        output_headers(1, 1, 1, 0, 0, 0);
00431        wc_printf("Session: %d<hr />\n", WC->wc_session);
00432        wc_printf("Command: <br><PRE>\n");
00433 /*     
00434 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment1, 0, 0);
00435        wc_printf("<br>\n");
00436 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment12 0, 0);
00437        wc_printf("<br>\n");
00438 StrEscAppend(WC->WBuf, NULL, WC->UrlFragment3, 0, 0);
00439 */
00440        wc_printf("</PRE><hr />\n");
00441        wc_printf("Variables: <br><PRE>\n");
00442        dump_vars();
00443        wc_printf("</PRE><hr />\n");
00444        wDumpContent(1);
00445 }
00446 
00447 
00448 void tmplput_url_part(StrBuf *Target, WCTemplputParams *TP)
00449 {
00450        StrBuf *Name = NULL;
00451        StrBuf *UrlBuf = NULL;
00452        wcsession *WCC = WC;
00453        
00454        if (WCC != NULL) {
00455               long n;
00456 
00457               n = GetTemplateTokenNumber(Target, TP, 0, 0);
00458               if (n == 0) {
00459                      if (WCC->Hdr->HR.Handler != NULL)
00460                             UrlBuf = Name = WCC->Hdr->HR.Handler->Name;
00461               }
00462               else if (n == 1) {
00463                      UrlBuf = NewStrBuf();
00464                      StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 0, '/');
00465               }
00466               else {
00467                      UrlBuf = NewStrBuf();
00468                      StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 1, '/');
00469               }
00470 
00471               if (UrlBuf == NULL)  {
00472                      LogTemplateError(Target, "urlbuf", ERR_PARM1, TP, "not set.");
00473               }
00474               StrBufAppendTemplate(Target, TP, UrlBuf, 2);
00475               if (Name == NULL) FreeStrBuf(&UrlBuf);
00476        }
00477 }
00478 
00479 
00480 void 
00481 InitModule_PARAMHANDLING
00482 (void)
00483 {
00484        WebcitAddUrlHandler(HKEY("diagnostics"), "", 0, diagnostics, NEED_URL);
00485 
00486        RegisterConditional(HKEY("COND:BSTR"), 1, ConditionalBstr, CTX_NONE);
00487        RegisterNamespace("BSTR", 1, 2, tmplput_bstr, NULL, CTX_NONE);
00488        RegisterNamespace("BSTR:FORWARD", 1, 2, tmplput_bstrforward, NULL, CTX_NONE);
00489        RegisterNamespace("URLPART", 1, 2, tmplput_url_part, NULL, CTX_NONE);
00490 }
00491 
00492 
00493 void
00494 SessionAttachModule_PARAMHANDLING
00495 (wcsession *sess)
00496 {
00497        sess->Hdr->urlstrings = NewHash(1,NULL);
00498 }
00499 
00500 void
00501 SessionDetachModule_PARAMHANDLING
00502 (wcsession *sess)
00503 {
00504        DeleteHash(&sess->Hdr->urlstrings);
00505        FreeStrBuf(&sess->upload_filename);
00506 }