billbarker    02/05/10 22:06:26

  Modified:    catalina/src/share/org/apache/catalina/servlets
                        DefaultServlet.java
  Added:       catalina/src/share/org/apache/catalina/util IOTools.java
                        Strftime.java URLEncoder.java
  Log:
  Refactoring DefaultServlet to allow for common code with SSIServlet.
  
  As far as DefaultServlet, this is a pure re-factoring with no change to the code 
processed.  It should be a safe change.
  
  The new URLEncoder is very much like o.a.t.u.buf.UEncoder.  It might be good to 
merge the two, but by adding it for now, more people can review it.
  
  Submitted by: Dan Sandberg [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.55      +19 -89    
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java
  
  Index: DefaultServlet.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- DefaultServlet.java       17 Apr 2002 05:49:59 -0000      1.54
  +++ DefaultServlet.java       11 May 2002 05:06:25 -0000      1.55
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
 1.54 2002/04/17 05:49:59 billbarker Exp $
  - * $Revision: 1.54 $
  - * $Date: 2002/04/17 05:49:59 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java,v
 1.55 2002/05/11 05:06:25 billbarker Exp $
  + * $Revision: 1.55 $
  + * $Date: 2002/05/11 05:06:25 $
    *
    * ====================================================================
    *
  @@ -80,7 +80,6 @@
   import java.io.OutputStreamWriter;
   import java.net.MalformedURLException;
   import java.net.URL;
  -import java.net.URLEncoder;
   import java.sql.Timestamp;
   import java.util.Date;
   import java.util.Enumeration;
  @@ -89,7 +88,6 @@
   import java.util.Locale;
   import java.util.TimeZone;
   import java.util.Hashtable;
  -import java.util.BitSet;
   import java.text.ParseException;
   import java.text.SimpleDateFormat;
   import java.security.MessageDigest;
  @@ -117,6 +115,7 @@
   import org.apache.catalina.util.RequestUtil;
   import org.apache.catalina.util.ServerInfo;
   import org.apache.catalina.util.StringManager;
  +import org.apache.catalina.util.URLEncoder;
   
   
   /**
  @@ -125,7 +124,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.54 $ $Date: 2002/04/17 05:49:59 $
  + * @version $Revision: 1.55 $ $Date: 2002/05/11 05:06:25 $
    */
   
   public class DefaultServlet
  @@ -195,14 +194,27 @@
   
       protected final static TimeZone gmtZone = TimeZone.getTimeZone("GMT");
   
  +    /**
  +     * Array containing the safe characters set.
  +     */
  +    protected static URLEncoder urlEncoder;
  +
   
       /**
        * GMT timezone - all HTTP dates are on GMT
        */
  +    // ----------------------------------------------------- Static Initializer
       static {
           formats[0].setTimeZone(gmtZone);
           formats[1].setTimeZone(gmtZone);
           formats[2].setTimeZone(gmtZone);
  +
  +        urlEncoder = new URLEncoder();
  +        urlEncoder.addSafeCharacter('-');
  +        urlEncoder.addSafeCharacter('_');
  +        urlEncoder.addSafeCharacter('.');
  +        urlEncoder.addSafeCharacter('*');
  +        urlEncoder.addSafeCharacter('/');
       }
   
   
  @@ -226,45 +238,11 @@
   
   
       /**
  -     * Array containing the safe characters set.
  -     */
  -    protected static BitSet safeCharacters;
  -
  -
  -    protected static final char[] hexadecimal =
  -    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  -     'A', 'B', 'C', 'D', 'E', 'F'};
  -
  -
  -    /**
        * Size of file transfer buffer in bytes.
        */
       private static final int BUFFER_SIZE = 4096;
   
   
  -    // ----------------------------------------------------- Static Initializer
  -
  -
  -    static {
  -        safeCharacters = new BitSet(256);
  -        int i;
  -        for (i = 'a'; i <= 'z'; i++) {
  -            safeCharacters.set(i);
  -        }
  -        for (i = 'A'; i <= 'Z'; i++) {
  -            safeCharacters.set(i);
  -        }
  -        for (i = '0'; i <= '9'; i++) {
  -            safeCharacters.set(i);
  -        }
  -        safeCharacters.set('-');
  -        safeCharacters.set('_');
  -        safeCharacters.set('.');
  -        safeCharacters.set('*');
  -        safeCharacters.set('/');
  -    }
  -
  -
       // --------------------------------------------------------- Public Methods
   
   
  @@ -1016,55 +994,7 @@
        * @param path Path which has to be rewiten
        */
       protected String rewriteUrl(String path) {
  -
  -        /**
  -         * Note: This code portion is very similar to URLEncoder.encode.
  -         * Unfortunately, there is no way to specify to the URLEncoder which
  -         * characters should be encoded. Here, ' ' should be encoded as "%20"
  -         * and '/' shouldn't be encoded.
  -         */
  -
  -        int maxBytesPerChar = 10;
  -        int caseDiff = ('a' - 'A');
  -        StringBuffer rewrittenPath = new StringBuffer(path.length());
  -        ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
  -        OutputStreamWriter writer = null;
  -        try {
  -            writer = new OutputStreamWriter(buf, "UTF8");
  -        } catch (Exception e) {
  -            e.printStackTrace();
  -            writer = new OutputStreamWriter(buf);
  -        }
  -
  -        for (int i = 0; i < path.length(); i++) {
  -            int c = (int) path.charAt(i);
  -            if (safeCharacters.get(c)) {
  -                rewrittenPath.append((char)c);
  -            } else {
  -                // convert to external encoding before hex conversion
  -                try {
  -                    writer.write(c);
  -                    writer.flush();
  -                } catch(IOException e) {
  -                    buf.reset();
  -                    continue;
  -                }
  -                byte[] ba = buf.toByteArray();
  -                for (int j = 0; j < ba.length; j++) {
  -                    // Converting each byte in the buffer
  -                    byte toEncode = ba[j];
  -                    rewrittenPath.append('%');
  -                    int low = (int) (toEncode & 0x0f);
  -                    int high = (int) ((toEncode & 0xf0) >> 4);
  -                    rewrittenPath.append(hexadecimal[high]);
  -                    rewrittenPath.append(hexadecimal[low]);
  -                }
  -                buf.reset();
  -            }
  -        }
  -
  -        return rewrittenPath.toString();
  -
  +        return urlEncoder.encode( path );
       }
   
   
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/IOTools.java
  
  Index: IOTools.java
  ===================================================================
  /*
   * IOTools.java
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/IOTools.java,v
 1.1 2002/05/11 05:06:25 billbarker Exp $
   * $Revision: 1.1 $
   * $Date: 2002/05/11 05:06:25 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  package org.apache.catalina.util;
  
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.io.Reader;
  import java.io.Writer;
  
  
  /**
   * Contains commonly needed I/O-related methods 
   *
   * @author Dan Sandberg
   */
  public class IOTools {
      protected final static int DEFAULT_BUFFER_SIZE=4*1024; //4k
  
      //Ensure non-instantiability
      private IOTools() {
      }
  
       /**
       * Read input from reader and write it to writer until there is no more
       * input from reader.
       *
       * @param reader the reader to read from.
       * @param writer the writer to write to.
       * @param buf the char array to use as a bufferx
       */
      public static void flow( Reader reader, Writer writer, char[] buf ) 
          throws IOException {
          int numRead;
          while ( (numRead = reader.read(buf) ) >= 0) {
              writer.write(buf, 0, numRead);
          }
      }
  
      /**
       * @see flow( Reader, Writer, char[] )
       */
      public static void flow( Reader reader, Writer writer ) 
          throws IOException {
          char[] buf = new char[DEFAULT_BUFFER_SIZE];
          flow( reader, writer, buf );
      }
  
      /**
       * Read input from input stream and write it to output stream 
       * until there is no more input from input stream.
       *
       * @param input stream the input stream to read from.
       * @param output stream the output stream to write to.
       * @param buf the byte array to use as a buffer
       */
      public static void flow( InputStream is, OutputStream os, byte[] buf ) 
          throws IOException {
          int numRead;
          while ( (numRead = is.read(buf) ) >= 0) {
              os.write(buf, 0, numRead);
          }
      }  
  
      /**
       * @see flow( Reader, Writer, byte[] )
       */ 
      public static void flow( InputStream is, OutputStream os ) 
          throws IOException {
          byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
          flow( is, os, buf );
      }
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/Strftime.java
  
  Index: Strftime.java
  ===================================================================
  /*
   * Strftime.java
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/Strftime.java,v
 1.1 2002/05/11 05:06:25 billbarker Exp $
   * $Revision: 1.1 $
   * $Date: 2002/05/11 05:06:25 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.catalina.util;
  
  import java.text.SimpleDateFormat;
  import java.util.Properties;
  import java.util.Date;
  import java.util.Locale;
  import java.util.TimeZone;
  
  /**
   * Converts dates to strings using the same format specifiers as strftime
   *
   * Note: This does not mimic strftime perfectly.  Certain strftime commands, 
   *       are not supported, and will convert as if they were literals.
   *
   *       Certain complicated commands, like those dealing with the week of the year
   *       probably don't have exactly the same behavior as strftime.
   *
   *       These limitations are due to use SimpleDateTime.  If the conversion was done
   *       manually, all these limitations could be eliminated.
   *
   *       The interface looks like a subset of DateFormat.  Maybe someday someone 
will make this class
   *       extend DateFormat.
   *
   * @author Bip Thelin
   * @author Dan Sandberg
   * @version $Revision: 1.1 $, $Date: 2002/05/11 05:06:25 $
   */
  public class Strftime {
      protected static Properties translate;
      protected SimpleDateFormat simpleDateFormat;
  
      /**
       * Initialize our pattern translation
       */
      static {
          translate = new Properties();
          translate.put("a","EEE");
          translate.put("A","EEEE");
          translate.put("b","MMM");
          translate.put("B","MMMM");
          translate.put("c","EEE MMM d HH:mm:ss yyyy");
  
        //There's no way to specify the century in SimpleDateFormat.  We don't want to 
hard-code
        //20 since this could be wrong for the pre-2000 files.
          //translate.put("C", "20");
          translate.put("d","dd");
          translate.put("D","MM/dd/yy");
          translate.put("e","dd"); //will show as '03' instead of ' 3'
          translate.put("F","yyyy-MM-dd");
          translate.put("g","yy");
          translate.put("G","yyyy");
          translate.put("H","HH");
          translate.put("h","MMM");
          translate.put("I","hh");
          translate.put("j","DDD");
          translate.put("k","HH"); //will show as '07' instead of ' 7'
          translate.put("l","hh"); //will show as '07' instead of ' 7'
          translate.put("m","MM");
          translate.put("M","mm");
          translate.put("n","\n");
          translate.put("p","a");
          translate.put("P","a");  //will show as pm instead of PM
          translate.put("r","hh:mm:ss a");
          translate.put("R","HH:mm");
        //There's no way to specify this with SimpleDateFormat
          //translate.put("s","seconds since ecpoch");
          translate.put("S","ss");
          translate.put("t","\t");
          translate.put("T","HH:mm:ss");
        //There's no way to specify this with SimpleDateFormat
          //translate.put("u","day of week ( 1-7 )");
  
        //There's no way to specify this with SimpleDateFormat
          //translate.put("U","week in year with first sunday as first day...");
  
          translate.put("V","ww"); //I'm not sure this is always exactly the same
  
        //There's no way to specify this with SimpleDateFormat
          //translate.put("W","week in year with first monday as first day...");
  
        //There's no way to specify this with SimpleDateFormat
          //translate.put("w","E");
          translate.put("X","HH:mm:ss");
          translate.put("x","MM/dd/yy");
          translate.put("y","yy");
          translate.put("Y","yyyy");
          translate.put("Z","z");
          translate.put("z","Z");
          translate.put("%","%");
      }
  
  
      /**
       * Create an instance of this date formatting class
       *
       * @see #Strftime( String, Locale )
       */
      public Strftime( String origFormat ) {
        String convertedFormat = convertDateFormat( origFormat );
        simpleDateFormat = new SimpleDateFormat( convertedFormat );
      }
  
      /**
       * Create an instance of this date formatting class
       * 
       * @param origFormat the strftime-style formatting string
       * @param the locale to use for locale-specific conversions
       */
      public Strftime( String origFormat, Locale locale ) {
        String convertedFormat = convertDateFormat( origFormat );
        simpleDateFormat = new SimpleDateFormat( convertedFormat, locale );
      }
  
      /**
       * Format the date according to the strftime-style string given in the 
constructor.
       *
       * @param date the date to format
       * @return the formatted date
       */
      public String format( Date date ) {
        return simpleDateFormat.format( date );
      }
  
      /**
       * Get the timezone used for formatting conversions
       *
       * @return the timezone
       */
      public TimeZone getTimeZone() {
        return simpleDateFormat.getTimeZone();
      }
  
      /**
       * Change the timezone used to format dates
       *
       * @see java.util.TimeZone#setTimeZone
       */
      public void setTimeZone( TimeZone timeZone ) {
        simpleDateFormat.setTimeZone( timeZone );
      }
  
      /**
       * Search the provided pattern and get the C standard
       * Date/Time formatting rules and convert them to the
       * Java equivalent.
       *
       * @param pattern The pattern to search
       * @return The modified pattern
       */
      protected String convertDateFormat( String pattern ) {
          boolean inside = false;
          boolean mark = false;
        boolean modifiedCommand = false;
  
          StringBuffer buf = new StringBuffer();
  
          for(int i = 0; i < pattern.length(); i++) {
            char c = pattern.charAt(i);
  
              if ( c=='%' && !mark ) {
                  mark=true;
              } else {
                if ( mark ) {
                    if ( modifiedCommand ) {
                        //don't do anything--we just wanted to skip a char
                        modifiedCommand = false;
                        mark = false;
                    } else {
                        inside = translateCommand( buf, pattern, i, inside );
                        //It's a modifier code
                        if ( c=='O' || c=='E' ) {
                            modifiedCommand = true;
                        } else {
                            mark=false;
                        }
                    }
                } else {
                    if ( !inside && c != ' ' ) {
                        //We start a literal, which we need to quote
                        buf.append("'");
                        inside = true;
                    }
                    
                    buf.append(c);
                }
            }
          }
  
        if ( buf.length() > 0 ) {
            char lastChar = buf.charAt( buf.length() - 1 );
  
            if( lastChar!='\'' && inside ) {
                buf.append('\'');
            }
        }
          return buf.toString();
      }
  
      protected String quote( String str, boolean insideQuotes ) {
        String retVal = str;
        if ( !insideQuotes ) {
            retVal = '\'' + retVal + '\'';
        }
        return retVal;
      }
  
      /**
       * try to get the Java Date/Time formating associated with
       * the C standard provided
       *
       * @param c The C equivalent to translate
       * @return The Java formatting rule to use
       */
      protected boolean translateCommand( StringBuffer buf, String pattern, int index, 
boolean oldInside ) {
        char firstChar = pattern.charAt( index );
        boolean newInside = oldInside;
  
        //O and E are modifiers, they mean to present an alternative representation of 
the next char
        //we just handle the next char as if the O or E wasn't there
        if ( firstChar == 'O' || firstChar == 'E' ) {
            if ( index + 1 < pattern.length() ) {               
                newInside = translateCommand( buf, pattern, index + 1, oldInside );
            } else {
                buf.append( quote("%" + firstChar, oldInside ) );
            }
        } else {
            String command = translate.getProperty( String.valueOf( firstChar ) );
            
            //If we don't find a format, treat it as a literal--That's what apache does
            if ( command == null ) {
                buf.append( quote( "%" + firstChar, oldInside ) );
            } else {
                //If we were inside quotes, close the quotes
                if ( oldInside ) {
                    buf.append( '\'' );
                }
                buf.append( command );
                newInside = false;
            }
        }
        return newInside;
      }
  }
  
  
  
  1.1                  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/URLEncoder.java
  
  Index: URLEncoder.java
  ===================================================================
  /*
   * URLEncoder.java
   * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/URLEncoder.java,v
 1.1 2002/05/11 05:06:25 billbarker Exp $
   * $Revision: 1.1 $
   * $Date: 2002/05/11 05:06:25 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  package org.apache.catalina.util;
  
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.util.BitSet;
  
  /**
   *
   * This class is very similar to the java.net.URLEncoder class.
   *
   * Unfortunately, with java.net.URLEncoder there is no way to specify to the 
   * java.net.URLEncoder which characters should NOT be encoded.
   *
   * This code was moved from DefaultServlet.java
   *
   * @author Craig R. McClanahan
   * @author Remy Maucherat
   */
  public class URLEncoder {
      protected static final char[] hexadecimal =
      {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
       'A', 'B', 'C', 'D', 'E', 'F'};
  
      //Array containing the safe characters set.
      protected BitSet safeCharacters = new BitSet(256);
  
      public URLEncoder() {
          for (char i = 'a'; i <= 'z'; i++) {
              addSafeCharacter(i);
          }
          for (char i = 'A'; i <= 'Z'; i++) {
              addSafeCharacter(i);
          }
          for (char i = '0'; i <= '9'; i++) {
              addSafeCharacter(i);
          }
      }
  
      public void addSafeCharacter( char c ) {
        safeCharacters.set( c );
      }
  
      public String encode( String path ) {
          int maxBytesPerChar = 10;
          int caseDiff = ('a' - 'A');
          StringBuffer rewrittenPath = new StringBuffer(path.length());
          ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
          OutputStreamWriter writer = null;
          try {
              writer = new OutputStreamWriter(buf, "UTF8");
          } catch (Exception e) {
              e.printStackTrace();
              writer = new OutputStreamWriter(buf);
          }
  
          for (int i = 0; i < path.length(); i++) {
              int c = (int) path.charAt(i);
              if (safeCharacters.get(c)) {
                  rewrittenPath.append((char)c);
              } else {
                  // convert to external encoding before hex conversion
                  try {
                      writer.write(c);
                      writer.flush();
                  } catch(IOException e) {
                      buf.reset();
                      continue;
                  }
                  byte[] ba = buf.toByteArray();
                  for (int j = 0; j < ba.length; j++) {
                      // Converting each byte in the buffer
                      byte toEncode = ba[j];
                      rewrittenPath.append('%');
                      int low = (int) (toEncode & 0x0f);
                      int high = (int) ((toEncode & 0xf0) >> 4);
                      rewrittenPath.append(hexadecimal[high]);
                      rewrittenPath.append(hexadecimal[low]);
                  }
                  buf.reset();
              }
          }
          return rewrittenPath.toString();
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to