home *** CD-ROM | disk | FTP | other *** search
/ CGI How-To / CGI HOW-TO.iso / chap9 / encoder / cgilib.pl next >
Encoding:
Perl Script  |  1996-06-15  |  4.6 KB  |  257 lines

  1. #!/usr/local/bin/perl
  2.  
  3. # This file contains the subroutines needed to 
  4. # read CGI input. To use the library,
  5. # call the subroutines readData and parseData.
  6. #
  7. # &readData(*data);
  8. # &parseData(*data,*dataDict);
  9. #
  10. # Read data takes a scalar by name, and parse data,
  11. # uses that scalar and a dictionary by name. The
  12. # dictionary is filled with the key-value pairs of
  13. # data from the CGI scripts input.
  14. # You can also use the convience routine
  15. # readParse, that take the name of a dictionary.
  16. #
  17. # &readParse(*dataDict);
  18. #
  19. # Subroutine for decoding form data
  20.  
  21. sub decodeData
  22. {
  23.     local(*queryString) = @_ if @_;
  24.     
  25.     #convert pluses to spaces
  26.     
  27.     $queryString =~ s/\+/ /g;
  28.  
  29.     # Convert the hex codes
  30.     #
  31.     # First find them with s/%(..)//ge,
  32.     # then turn the found hexcode into a decimal number,
  33.     # then pack the decimal number into character form,
  34.     # then do normal substitution.
  35.      
  36.     $queryString =~ s/%([0-9A-Fa-f]{2})/pack("c",hex($1))/ge; 
  37.     
  38.     # Return 1 for success
  39.         
  40.     return 1;
  41. }
  42.  
  43. # Subroutine for encoding data
  44. # This subroutine is very conservitive and converts
  45. # Some characters that it doesnt need to
  46.  
  47. sub encodeData
  48. {
  49.     local($queryString) = @_ if @_;
  50.     
  51.     # Convert the hex codes
  52.     #
  53.     # First find them 
  54.     # then turn the found 
  55.     # then do normal substitution.
  56.      
  57.     $queryString =~ s/([^a-zA-Z0-9+ ])/sprintf("%%%lx",ord($1))/ge; 
  58.  
  59.     #convert pluses to spaces
  60.     
  61.     $queryString =~ s/ /\+/g;
  62.     
  63.     $queryString = "" unless $queryString;
  64.  
  65.     # Return 1 for success
  66.         
  67.     return $queryString;
  68. }
  69.  
  70. # Subroutine that converts a dictionary
  71. # into a cgi encoded string
  72.  
  73. sub encodeDictionary
  74. {
  75.     local(*formData) = @_;
  76.     local($returnString,$key,$needAmp);
  77.  
  78.     $needAmp = 0;
  79.  
  80.     foreach $key (keys(%formData))
  81.     {
  82.     if($key =~ /^A_/)
  83.     {
  84.         if($needAmp)
  85.         {
  86.         $returnString .= "&";
  87.         }
  88.         
  89.         $returnString .= &encodeData($key);
  90.         $returnString .= "=";
  91.         $returnString .= &encodeData($formData{$key});
  92.     
  93.         $needAmp = 1;
  94.     }
  95.     }
  96.  
  97.     return $returnString;
  98. }
  99.  
  100. # Subroutine for interpreting form data
  101.  
  102. sub parseData
  103. {
  104.     local(*queryString,*formData) = @_ if @_;
  105.     
  106.     local($key,$value,$curString,@tmpArray,$aName);
  107.     
  108.     # Split the string into key-value pairs, using the '&' character
  109.     
  110.     @tmpArray = split(/&/,$queryString);
  111.     
  112.     # Loop over each pair found
  113.     
  114.     foreach $curString (@tmpArray)
  115.     {
  116.         # Split the key and value, using the '=' character
  117.         
  118.         ($key,$value) = split(/=/,$curString);
  119.         
  120.         # Decode the key and value
  121.         
  122.         &decodeData(*key);
  123.         &decodeData(*value);
  124.         
  125.         # Add the keys and values to the dictionary
  126.         #
  127.         # We will store multple values under a new name,
  128.         # as a string, using the format, value1\376value2...
  129.         # Where \376 is a character unlikely to appear in the
  130.         # values.
  131.         
  132.         if($formData{$key}) # See if this is a multiple value
  133.         {
  134.             $aName = "A_".$key; # Make a new key
  135.             
  136.             if($formData{$aName}) #Check if the array already exists
  137.             {
  138.                 $formData{$aName} .= "\376";
  139.                 $formData{$aName} .= $value;
  140.                 
  141.                 # Also put the newest value in the dictionary
  142.                 # at the real key.
  143.                 
  144.                 $formData{$key} = $value;
  145.                 
  146.             }
  147.             else #If not, create it and add the current value to the array
  148.             {
  149.                 # Add the 1st value for the key to the string
  150.                 $formData{$aName} = $formData{$key};
  151.                 
  152.                 # Add the one that we just found
  153.                 
  154.                 $formData{$aName} .= "\376";
  155.                 $formData{$aName} .= $value;
  156.                 
  157.                 # Also put the newest value in the dictionary
  158.                 # at the real key.
  159.                 
  160.                 $formData{$key} = $value;
  161.             }
  162.         }
  163.         else # Just add it
  164.         {
  165.             $formData{$key} = $value;
  166.         }
  167.     }
  168.  
  169.     return 1;
  170. }
  171.  
  172. # Subroutine for reading post data
  173.  
  174. sub readPostData
  175. {
  176.     local(*queryString) = @_ if @_;
  177.  
  178.     local($contentLength);
  179.     
  180.     # Read the environment variable CONTENT_LENGTH
  181.     
  182.     $contentLength = $ENV{"CONTENT_LENGTH"};
  183.     
  184.     # Make sure that there is data to read
  185.     
  186.     if($contentLength)
  187.     {
  188.         # Read contentLength characters from STDIN into queryString
  189.         
  190.         read(STDIN,$queryString,$contentLength);
  191.     }
  192.  
  193.     # Return 1 for success
  194.     
  195.     return 1;
  196. }
  197.  
  198. sub readGetData
  199. {
  200.     local(*queryString) = @_ if @_;
  201.  
  202.     # Read the environment variable QUERY_STRING
  203.  
  204.     $queryString = $ENV{"QUERY_STRING"};
  205.     
  206.     return 1;
  207. }
  208.  
  209. sub readData
  210. {
  211.     local(*queryString) = @_ if @_;
  212.     
  213.     # Read the envorinmental variable REQUEST_METHOD
  214.     
  215.     $requestType = $ENV{"REQUEST_METHOD"};
  216.     
  217.     # If the request is GET use readGetData
  218.     # otherwise, if the request is POST use readPostData
  219.     
  220.     if($requestType eq "GET")
  221.     {
  222.         &readGetData(*queryString);
  223.     }
  224.     elsif($requestType eq "POST")
  225.     {
  226.         &readPostData(*queryString);
  227.     }
  228.  
  229.     $queryString = "" unless $queryString;
  230.  
  231. }
  232.  
  233. # Read parse takes the name of a dictionary, and fills
  234. # it with GET or POST cgi data.
  235.  
  236. sub readParse
  237. {
  238.     local(*dataDict) = @_;
  239.     local($data);
  240.  
  241.  
  242.     &readData(*data);
  243.     if($data)
  244.     {
  245.     &parseData(*data,*dataDict);
  246.     }
  247. }
  248.  
  249. 1;
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.