lib/cgi/cgi-args.cc
changeset 0 6f7a81934006
equal deleted inserted replaced
-1:000000000000 0:6f7a81934006
       
     1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
       
     2 //
       
     3 // This program is free software; you can redistribute it and/or modify
       
     4 // it under the terms of the GNU General Public License as published by
       
     5 // the Free Software Foundation; either version 2 of the License, or
       
     6 // (at your option) any later version.
       
     7 //
       
     8 // This program is distributed in the hope that it will be useful,
       
     9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    11 // GNU General Public License for more details.
       
    12 //
       
    13 // You should have received a copy of the GNU General Public License
       
    14 // along with this program; if not, write to the Free Software
       
    15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    16 
       
    17 #include <config.h>
       
    18 #include <stdlib.h>
       
    19 #include <sys/types.h>
       
    20 #include "cgi-args.h"
       
    21 #include "fdbuf/fdbuf.h"
       
    22 
       
    23 // These routines are optimized for the common case:
       
    24 // - few variables (less than ten)
       
    25 // - short strings (less than 1K each)
       
    26 // - infrequent access relative to the remainder of the code
       
    27 
       
    28 CGIArgs::~CGIArgs()
       
    29 {
       
    30   if(head)
       
    31     delete head;
       
    32 }
       
    33 
       
    34 bool CGIArgs::exists(mystring var) const
       
    35 {
       
    36   for(arg* ptr = head; ptr; ptr = ptr->next)
       
    37     if(ptr->var == var)
       
    38       return true;
       
    39   return false;
       
    40 }
       
    41 
       
    42 mystring CGIArgs::get(mystring var, mystring dflt) const
       
    43 {
       
    44   for(arg* ptr = head; ptr; ptr = ptr->next)
       
    45     if(ptr->var == var)
       
    46       return ptr->val;
       
    47   return dflt;
       
    48 }
       
    49 
       
    50 void CGIArgs::append(mystring var, mystring val)
       
    51 {
       
    52   arg* newarg = new arg(var, val);
       
    53   if(tail)
       
    54     tail->next = newarg;
       
    55   else
       
    56     head = newarg;
       
    57   tail = newarg;
       
    58   ++argc;
       
    59 }
       
    60 
       
    61 static inline int fromhex(char ch)
       
    62 {
       
    63   if(ch >= '0' && ch <= '9')
       
    64     return ch - '0';
       
    65   else if(ch >= 'a' && ch <= 'f')
       
    66     return ch - 'a' + 0xa;
       
    67   else if(ch >= 'A' && ch <= 'F')
       
    68     return ch - 'A' + 0xa;
       
    69   else
       
    70     return -1;
       
    71 }
       
    72 
       
    73 static bool get_parts(mystring& var, mystring& val)
       
    74 {
       
    75   if(!fin) return false;
       
    76 #define BUFSIZE 1024
       
    77   char buf[BUFSIZE];
       
    78   int i = 0;
       
    79   char ch;
       
    80   bool havevar = false;
       
    81   while(fin.get(ch)) {
       
    82     switch(ch) {
       
    83     case '+':
       
    84       buf[i++] = ' ';
       
    85       break;
       
    86     case '%':
       
    87       char ch1, ch2;
       
    88       if(fin.get(ch1) && fin.get(ch2))
       
    89 	buf[i++] = fromhex(ch1) << 4 | fromhex(ch2);
       
    90       break;
       
    91     case '=':
       
    92       if(havevar)
       
    93 	buf[i++] = ch;
       
    94       else {
       
    95 	buf[i] = 0;
       
    96 	var += buf;
       
    97 	i = 0;
       
    98 	havevar = true;
       
    99       }
       
   100       break;
       
   101     case '&':
       
   102       buf[i] = 0;
       
   103       if(havevar)
       
   104 	val += buf;
       
   105       else
       
   106 	var += buf;
       
   107       return true;
       
   108     default:
       
   109       buf[i++] = ch;
       
   110     }
       
   111     if(i >= BUFSIZE-1) {
       
   112       buf[i] = 0;
       
   113       if(!havevar) var += buf;
       
   114       else val += buf;
       
   115       i = 0;
       
   116     }
       
   117   }
       
   118   if(havevar) {
       
   119     buf[i] = 0;
       
   120     val += buf;
       
   121   }
       
   122   return havevar;
       
   123 }
       
   124 
       
   125 void CGIArgs::init()
       
   126 {
       
   127   mystring method = getenv("REQUEST_METHOD");
       
   128   mystring content = getenv("CONTENT_TYPE");
       
   129   if(method != "POST" && method != "post")
       
   130     errstr = "Must be accessed via a CGI 'POST' form";
       
   131   else if(content == "multipart/form-data")
       
   132     errstr = "Must be accessed via a CGI 'POST' form";
       
   133   else {
       
   134     for(;;) {
       
   135       mystring var;
       
   136       mystring val;
       
   137       if(!get_parts(var, val))
       
   138 	break;
       
   139       append(var, val);
       
   140     }
       
   141   }
       
   142 }