home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / VCAFE.3.0A / Main.bin / HttpUtils.java < prev    next >
Text File  |  1998-04-21  |  7KB  |  214 lines

  1. /*
  2.  * @(#)HttpUtils.java    1.14 98/04/15
  3.  * 
  4.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.0
  20.  */
  21.  
  22. package javax.servlet.http;
  23.  
  24. import javax.servlet.ServletInputStream;
  25. import java.util.Hashtable;
  26. import java.util.StringTokenizer;
  27. import java.io.IOException;
  28.  
  29. /**
  30.  * A collection of static utility methods useful to HTTP servlets.
  31.  *
  32.  * @version 1.14
  33.  */
  34. public class HttpUtils {
  35.  
  36.     static Hashtable nullHashtable = new Hashtable();
  37.     
  38.     /**
  39.      * Creates an empty HttpUtils object.
  40.      */
  41.     public HttpUtils() {}
  42.  
  43.     /**
  44.      * Parses a query string and builds a hashtable of key-value
  45.      * pairs, where the values are arrays of strings.  The query string
  46.      * should have the form of a string packaged by the GET or POST
  47.      * method.  (For example, it should have its key-value pairs
  48.      * delimited by ampersands (&) and its keys separated from its
  49.      * values by equal signs (=).)
  50.      * 
  51.      * <p> A key can appear one or more times in the query string.
  52.      * Each time a key appears, its corresponding value is inserted
  53.      * into its string array in the hash table.  (So keys that appear
  54.      * once in the query string have, in the hash table, a string array
  55.      * of length one as their value, keys that appear twice have a
  56.      * string array of length two, etc.)
  57.      * 
  58.      * <p> When the keys and values are moved into the hashtable, any
  59.      * plus signs (+) are returned to spaces and characters sent in
  60.      * hexadecimal notation (%xx) are converted back to characters.
  61.      * 
  62.      * @param s query string to be parsed
  63.      * @return a hashtable built from the parsed key-value pairs; the
  64.      *.hashtable's values are arrays of strings
  65.      * @exception IllegalArgumentException if the query string is
  66.      * invalid.
  67.      */
  68.     static public Hashtable parseQueryString(String s) {
  69.  
  70.     String valArray[] = null;
  71.     
  72.     if (s == null) {
  73.         throw new IllegalArgumentException();
  74.     }
  75.     Hashtable ht = new Hashtable();
  76.     StringBuffer sb = new StringBuffer();
  77.     StringTokenizer st = new StringTokenizer(s, "&");
  78.     while (st.hasMoreTokens()) {
  79.         String pair = (String)st.nextToken();
  80.         int pos = pair.indexOf('=');
  81.         if (pos == -1) {
  82.         throw new IllegalArgumentException();
  83.         }
  84.         String key = parseName(pair.substring(0, pos), sb);
  85.         String val = parseName(pair.substring(pos+1, pair.length()), sb);
  86.         if (ht.containsKey(key)) {
  87.         String oldVals[] = (String []) ht.get(key);
  88.         valArray = new String[oldVals.length + 1];
  89.         for (int i = 0; i < oldVals.length; i++) 
  90.             valArray[i] = oldVals[i];
  91.         valArray[oldVals.length] = val;
  92.         } else {
  93.         valArray = new String[1];
  94.         valArray[0] = val;
  95.         }
  96.         ht.put(key, valArray);
  97.     }
  98.     return ht;
  99.     }
  100.  
  101.     /**
  102.      * 
  103.      * Parses FORM data that is posted to the server using the HTTP
  104.      * POST method and the application/x-www-form-urlencoded mime
  105.      * type.
  106.      *
  107.      * @param len the length of the data in the input stream.
  108.      * @param in the input stream
  109.      * @return a hashtable of the parsed key, value pairs.  Keys
  110.      * with multiple values have their values stored as an array of strings
  111.      * @exception IllegalArgumentException if the POST data is invalid.
  112.      */
  113.     static public Hashtable parsePostData(int len, 
  114.                       ServletInputStream in) {
  115.  
  116.     int    inputLen, offset;
  117.     byte[] postedBytes = null;
  118.     String postedBody;
  119.  
  120.     if (len <=0)
  121.         return null;
  122.  
  123.     try {
  124.         //
  125.         // Make sure we read the entire POSTed body.
  126.         //
  127.         postedBytes = new byte [len];
  128.         offset = 0;
  129.         do {
  130.         inputLen = in.read (postedBytes, offset, len - offset);
  131.         if (inputLen <= 0)
  132.             throw new IOException ("short read");
  133.         offset += inputLen;
  134.         } while ((len - offset) > 0);
  135.  
  136.     } catch (IOException e) {
  137.         return nullHashtable;
  138.     }
  139.  
  140.     //
  141.     // XXX we shouldn't assume that the only kind of POST body
  142.     // is FORM data encoded using ASCII or ISO Latin/1 ... or
  143.     // that the body should always be treated as FORM data.
  144.     //
  145.     postedBody = new String (postedBytes, 0, 0, len);
  146.  
  147.     return parseQueryString(postedBody); 
  148.     }
  149.  
  150.  
  151.  
  152.  
  153.     /*
  154.      * Parse a name in the query string.
  155.      */
  156.     static private String parseName(String s, StringBuffer sb) {
  157.     sb.setLength(0);
  158.     for (int i = 0; i < s.length(); i++) {
  159.         char c = s.charAt(i);
  160.         switch (c) {
  161.           case '+':
  162.         sb.append(' ');
  163.         break;
  164.           case '%':
  165.         try {
  166.             sb.append((char) Integer.parseInt(s.substring(i+1, i+3), 
  167.                         16));
  168.         } catch (NumberFormatException e) {
  169.             throw new IllegalArgumentException();
  170.         }
  171.         i += 2;
  172.         break;
  173.           default:
  174.         sb.append(c);
  175.         break;
  176.         }
  177.     }
  178.     return sb.toString();
  179.     }
  180.  
  181.     /**
  182.      * Reconstructs the URL used by the client used to make the
  183.      * request.  This accounts for differences such as addressing
  184.      * scheme (http, https) and default ports, but does not attempt to
  185.      * include query parameters.  Since it returns a StringBuffer, not
  186.      * a String, the URL can be modified efficiently (for example, by
  187.      * appending query parameters).
  188.      *
  189.      * <P> This method is useful for creating redirect messages and for
  190.      * reporting errors.  */
  191.     public static StringBuffer getRequestURL (HttpServletRequest req) {
  192.     StringBuffer    url = new StringBuffer ();
  193.     String        scheme = req.getScheme ();
  194.     int        port = req.getServerPort ();
  195.  
  196.     String        servletPath = req.getServletPath ();
  197.     String        pathInfo = req.getPathInfo ();
  198.  
  199.     url.append (scheme);        // http, https
  200.     url.append ("://");
  201.     url.append (req.getServerName ());
  202.     if ((scheme.equals ("http") && port != 80)
  203.         || (scheme.equals ("https") && port != 443)) {
  204.         url.append (':');
  205.         url.append (req.getServerPort ());
  206.     }
  207.     if (servletPath != null)
  208.         url.append (servletPath);
  209.     if (pathInfo != null)
  210.         url.append (pathInfo);
  211.     return url;
  212.     }
  213. }
  214.