home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 November / APCD25112k.iso / feature / webserv / SAMBAR43.ZIP / _SETUP.1 / javaeng.jar / com / sambar / javaeng / SambarUtils.java < prev   
Encoding:
Java Source  |  2000-04-03  |  7.3 KB  |  259 lines

  1. /*
  2. **         Sambar Server JAVA Engine Implementation
  3. **
  4. **        Confidential Property of Tod Sambar
  5. **        (c) Copyright Tod Sambar 1999
  6. **        All rights reserved.
  7. */
  8. package com.sambar.javaeng;
  9.  
  10. import java.net.URLEncoder;
  11. import java.util.Date;
  12. import java.util.Vector;
  13. import java.util.StringTokenizer;
  14. import java.util.Locale;
  15. import java.util.TimeZone;
  16. import java.util.NoSuchElementException;
  17. import java.text.SimpleDateFormat;
  18. import javax.servlet.http.Cookie;
  19.  
  20. public final class SambarUtils
  21. {
  22.     public final static String URLEncode(String str) 
  23.     {
  24.         if (str == null)  
  25.             return null;
  26.         return URLEncoder.encode(str);
  27.     }
  28.  
  29.     /*
  30.     ** This method decodes the given urlencoded string.
  31.     **
  32.     ** @param  str the url-encoded string
  33.     ** @return the decoded string
  34.     ** @exception IllegalArgumentException If a '%' is not
  35.     ** followed by a valid 2-digit hex number.
  36.     */
  37.     public final static String URLDecode(String str)
  38.         throws IllegalArgumentException 
  39.     {
  40.         if (str == null)  
  41.             return  null;
  42.  
  43.         StringBuffer dec = new StringBuffer();    // decoded string output
  44.         int strPos = 0;
  45.         int strLen = str.length();
  46.  
  47.         dec.ensureCapacity(str.length());
  48.         while (strPos < strLen) 
  49.         {
  50.             int laPos;        // lookahead position
  51.  
  52.             // look ahead to next URLencoded metacharacter, if any
  53.             for (laPos = strPos; laPos < strLen; laPos++) 
  54.             {
  55.                 char laChar = str.charAt(laPos);
  56.                 if ((laChar == '+') || (laChar == '%')) 
  57.                     break;
  58.             }
  59.  
  60.             // if there were non-metacharacters, copy them all as a block
  61.             if (laPos > strPos) 
  62.             {
  63.                 dec.append(str.substring(strPos,laPos));
  64.                 strPos = laPos;
  65.             }
  66.  
  67.             // shortcut out of here if we're at the end of the string
  68.             if (strPos >= strLen)
  69.                 break;
  70.  
  71.             // process next metacharacter
  72.             char metaChar = str.charAt(strPos);
  73.             if (metaChar == '+') 
  74.             {
  75.                 dec.append(' ');
  76.                 strPos++;
  77.                 continue;
  78.             }
  79.             else if (metaChar == '%') 
  80.             {
  81.                 try 
  82.                 {
  83.                     dec.append((char)Integer.parseInt(str.substring(strPos + 1,
  84.                         strPos + 3), 16));
  85.                 } 
  86.                 catch (NumberFormatException e) 
  87.                 {
  88.                     throw new IllegalArgumentException("invalid hexadecimal "
  89.                         + str.substring(strPos + 1, strPos + 3)
  90.                         + " in URLencoded string (illegal unescaped '%'?)" );
  91.                 } 
  92.                 catch (StringIndexOutOfBoundsException e) 
  93.                 {
  94.                     throw new IllegalArgumentException("illegal unescaped '%' "
  95.                         + " in URLencoded string" );
  96.                 }
  97.                 strPos += 3;
  98.             }
  99.         }
  100.  
  101.         return dec.toString();
  102.     }
  103.  
  104.     /*
  105.     ** Parse a cookie header into an array of cookies as per
  106.     ** RFC2109 - HTTP Cookies
  107.     **
  108.     ** @param cookieHdr The Cookie header value.
  109.     */
  110.     public static Cookie[] parseCookies(String cookieHdr) 
  111.     {
  112.         Vector cookieJar = new Vector();
  113.  
  114.         if(cookieHdr == null || cookieHdr.length() == 0)
  115.             return new Cookie[0];
  116.  
  117.         StringTokenizer stok = new StringTokenizer(cookieHdr, "; ");
  118.         while (stok.hasMoreTokens()) 
  119.         {
  120.             try 
  121.             {
  122.                 String tok = stok.nextToken();
  123.                 int equals_pos = tok.indexOf('=');
  124.                 if (equals_pos > 0) 
  125.                 {
  126.                     String name = URLDecode(tok.substring(0, equals_pos));
  127.                     String value = URLDecode(tok.substring(equals_pos + 1));
  128.                     cookieJar.addElement(new Cookie(name, value));
  129.                 }
  130.                 else if ( tok.length() > 0 && equals_pos == -1 ) 
  131.                 {
  132.                     String name = URLDecode(tok);
  133.                     cookieJar.addElement(new Cookie(name, ""));
  134.                 }
  135.             }
  136.             catch (IllegalArgumentException badcookie) 
  137.             {
  138.             } 
  139.             catch (NoSuchElementException badcookie) 
  140.             {
  141.             }
  142.         }
  143.     
  144.         Cookie[] cookies = new Cookie[cookieJar.size()];
  145.         cookieJar.copyInto(cookies);
  146.         return cookies;
  147.     }
  148.  
  149.     private static SimpleDateFormat cookieDate =
  150.         new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zz", Locale.US );
  151.  
  152.     static 
  153.     {
  154.         cookieDate.setTimeZone(TimeZone.getTimeZone("GMT"));
  155.     }
  156.  
  157.     /*
  158.     ** Encode a cookie as per the Netscape Cookies specification. The
  159.     ** resulting string can be used in a Set-Cookie header.
  160.     **
  161.     ** @param cookie The cookie to encode.
  162.     ** @return A string following Netscape Cookies specification.
  163.     */
  164.     public static String encodeCookie(Cookie cookie) 
  165.     {
  166.         StringBuffer buf = new StringBuffer( cookie.getName() );
  167.         buf.append('=');
  168.         buf.append(cookie.getValue());
  169.  
  170.         long age = cookie.getMaxAge();
  171.         if (age > 0) 
  172.         {
  173.             buf.append("; expires=");
  174.             buf.append(cookieDate.format(
  175.                 new Date(System.currentTimeMillis() + (long)age * 1000 )));
  176.         }
  177.         else if (age == 0) 
  178.         {
  179.             buf.append("; expires=");
  180.             // Set expiration to the epoch to delete the cookie
  181.             buf.append(cookieDate.format(new Date(0)));
  182.         }
  183.  
  184.         if (cookie.getDomain() != null) 
  185.         {
  186.             buf.append("; domain=");
  187.             buf.append(cookie.getDomain());
  188.         }
  189.  
  190.         if (cookie.getPath() != null) 
  191.         {
  192.             buf.append("; path=");
  193.             buf.append(cookie.getPath());
  194.         }
  195.  
  196.         if (cookie.getSecure())
  197.             buf.append("; secure");
  198.  
  199.         return buf.toString();
  200.     }
  201.  
  202.     /*
  203.     ** Parse a content-type header for the character encoding. If the
  204.     ** content-type is null or there is no explicit character encoding,
  205.     ** ISO-8859-1 is returned.
  206.     **
  207.     ** @param contentType a content type header.
  208.     */
  209.     public static String parseCharacterEncoding(String contentType) 
  210.     {
  211.         int start;
  212.         int end;
  213.  
  214.         if ((contentType == null) || 
  215.             ((start = contentType.indexOf("charset="))) == -1 ) 
  216.         {
  217.             return "ISO-8859-1";
  218.         }
  219.  
  220.         String encoding = contentType.substring(start + 8);
  221.  
  222.         if ((end = encoding.indexOf(";")) > -1)
  223.             return encoding.substring(0, end);
  224.         else
  225.             return encoding;
  226.     }
  227.  
  228.     /*
  229.     ** Concatenate 2 paths, dealing with ..
  230.     ** ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d )
  231.     */
  232.     public static String catPath(String lookupPath, String path) 
  233.     {
  234.         // Cut off the last slash and everything beyond
  235.         int index = lookupPath.lastIndexOf("/");
  236.         lookupPath = lookupPath.substring(0, index);
  237.  
  238.         // Deal with .. by chopping dirs off the lookup path
  239.         while (path.startsWith("../")) 
  240.         {
  241.             if (lookupPath.length() > 0) 
  242.             {
  243.                 index = lookupPath.lastIndexOf("/");
  244.                 lookupPath = lookupPath.substring(0, index);
  245.             }
  246.             else 
  247.             {
  248.                 // More ..'s than dirs, return null
  249.                 return null;
  250.             }
  251.  
  252.             index = path.indexOf("../") + 3;
  253.             path = path.substring(index);
  254.         }
  255.  
  256.         return lookupPath + "/" + path;
  257.     }
  258. }
  259.