bip 01/04/26 15:58:50 Modified: catalina/src/share/org/apache/catalina/util/ssi ResponseIncludeWrapper.java ServletOutputStreamWrapper.java SsiCommand.java SsiConfig.java SsiEcho.java SsiFlastmod.java SsiFsize.java SsiInclude.java SsiMediator.java Log: Minor modifications and more Javadoc comments Revision Changes Path 1.2 +54 -23 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ResponseIncludeWrapper.java Index: ResponseIncludeWrapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ResponseIncludeWrapper.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ResponseIncludeWrapper.java 2001/03/27 20:38:00 1.1 +++ ResponseIncludeWrapper.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * ResponseIncludeWrapper.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ResponseIncludeWrapper.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ResponseIncludeWrapper.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -71,42 +71,73 @@ import javax.servlet.http.HttpServletResponseWrapper; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * A HttpServletResponseWrapper, used from <code>SsiInclude</code> * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class ResponseIncludeWrapper extends HttpServletResponseWrapper { + /** + * Our ServletOutputStream + */ private ServletOutputStream _out; + /** + * Variable to determine if we're using printwriter + */ private boolean printwriter = false; + /** + * Variable to determine if we're using outputstream + */ private boolean outputstream = false; + /** + * Initialize our wrapper with the current HttpServletResponse + * and ServletOutputStream. + * + * @param res The HttpServletResponse to use + * @param out The ServletOutputStream' to use + */ public ResponseIncludeWrapper(HttpServletResponse res, - ServletOutputStream out) { - super(res); - this._out = out; + ServletOutputStream out) { + super(res); + this._out = out; } - + + /** + * Return a printwriter, throws and exception if a + * OutputStream already been returned. + * + * @return a PrintWriter object + * @exception java.io.IOException if the outputstream already been called + */ public PrintWriter getWriter() - throws java.io.IOException { - if(!outputstream) { - printwriter=true; - return (new PrintWriter(_out)); - } else { - throw new IllegalStateException(); - } + throws java.io.IOException { + if(!outputstream) { + printwriter=true; + return (new PrintWriter(_out)); + } else { + throw new IllegalStateException(); + } } + /** + * Return a OutputStream, throws and exception if a + * printwriter already been returned. + * + * @return a OutputStream object + * @exception java.io.IOException if the printwriter already been called + */ public ServletOutputStream getOutputStream() - throws java.io.IOException { - if(!printwriter) { - outputstream=true; - return _out; - } else { - throw new IllegalStateException(); - } + throws java.io.IOException { + if(!printwriter) { + outputstream=true; + return _out; + } else { + throw new IllegalStateException(); + } } } 1.2 +30 -9 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ServletOutputStreamWrapper.java Index: ServletOutputStreamWrapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ServletOutputStreamWrapper.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ServletOutputStreamWrapper.java 2001/03/27 20:38:00 1.1 +++ ServletOutputStreamWrapper.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * ServletOutputStreamWrapper.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ServletOutputStreamWrapper.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/ServletOutputStreamWrapper.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -70,25 +70,46 @@ import javax.servlet.ServletOutputStream; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Class that extends ServletOuputStream, used as a wrapper + * from within <code>SsiInclude</code> * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ + * @see ServletOutputStream */ public final class ServletOutputStreamWrapper extends ServletOutputStream { + /** + * Our buffer to hold the stream + */ private ByteArrayOutputStream _buf = null; + /** + * Construct a new ServletOutputStream + * + */ public ServletOutputStreamWrapper() { - super(); - _buf = new ByteArrayOutputStream(); + super(); + _buf = new ByteArrayOutputStream(); } + /** + * Write our stream to the <code>OutputStream</code> provided. + * + * @param out the OutputStream to write this stream to + * @exception IOException if an input/output error occurs + */ public final void writeTo(OutputStream out) throws IOException { - out.write(_buf.toByteArray()); + out.write(_buf.toByteArray()); } + /** + * Write to our buffer + * + * @param b The parameter to write + */ public final void write(int b) { - _buf.write(b); + _buf.write(b); } } 1.2 +37 -9 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiCommand.java Index: SsiCommand.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiCommand.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiCommand.java 2001/03/27 20:38:00 1.1 +++ SsiCommand.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiCommand.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiCommand.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiCommand.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -65,20 +65,48 @@ package org.apache.catalina.util.ssi; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Interface implemented by the different SsiCommands. * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public interface SsiCommand { - + /** + * Get the processed result of this SsiCommands, + * called after and only if <code>isPrintable()</code> + * returns <code>true</code> + * + * @param strParamType The type of parameter + * @param strParam The value of the parameter + * @return result from this SsiCommand + */ public String getStream(String[] strParamType, - String[] strParam); + String[] strParam); + /** + * Process this request, used if <code>isPrintable()</code> + * returns false + * + * @param strParamType The type of parameter + * @param strParam The value of the parameter + */ public void process(String[] strParamType, - String[] strParam); + String[] strParam); + /** + * Called before <code>getStream()</code> and + * <code>process()</code>. Return <code>true</code> + * if this SsiCommand provide an output else <code>false</code> + * + * @return boolean result + */ public boolean isPrintable(); + /** + * Return <code>true</code> if this SsiCommand + * has been modified since the last request. + * + * @return a value of type 'boolean' + */ public boolean isModified(); - } 1.2 +148 -100 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiConfig.java Index: SsiConfig.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiConfig.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiConfig.java 2001/03/27 20:38:00 1.1 +++ SsiConfig.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiConfig.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiConfig.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiConfig.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -67,58 +67,90 @@ import java.util.Properties; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Implementation of the SsiCommand config, example of usage: + * <!--#config sizefmt="abbrev" errmsg="An error occured!"--> * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class SsiConfig extends SsiMediator implements SsiCommand { + /** + * Variable to hold if this SsiCommand modified or not + */ private boolean modified = false; + /** + * Variable to hold the errmsg to return + */ private byte[] errmsg; + /** + * Variable to hold which sizefmt to use + */ private String sizefmt; + /** + * Variable to hold which timefmt to use + */ private String timefmt; + /** + * Variable to hold the patterns for translation + */ private static Properties translate; + /** + * Initialize our pattern translation + */ static { - translate = new Properties(); - translate.put("a","EEE"); - translate.put("A","EEEE"); - translate.put("b","MMM"); - translate.put("h","MMM"); - translate.put("B","MMMM"); - translate.put("d","dd"); - translate.put("D","MM/dd/yy"); - translate.put("e","d"); - translate.put("H","HH"); - translate.put("I","hh"); - translate.put("j","E"); - translate.put("m","M"); - translate.put("M","m"); - translate.put("p","a"); - translate.put("r","hh:mm:ss a"); - translate.put("S","s"); - translate.put("T","HH:mm:ss"); - translate.put("U","w"); - translate.put("W","w"); - translate.put("w","E"); - translate.put("y","yy"); - translate.put("Y","yyyy"); - translate.put("z","z"); + translate = new Properties(); + translate.put("a","EEE"); + translate.put("A","EEEE"); + translate.put("b","MMM"); + translate.put("h","MMM"); + translate.put("B","MMMM"); + translate.put("d","dd"); + translate.put("D","MM/dd/yy"); + translate.put("e","d"); + translate.put("H","HH"); + translate.put("I","hh"); + translate.put("j","E"); + translate.put("m","M"); + translate.put("M","m"); + translate.put("p","a"); + translate.put("r","hh:mm:ss a"); + translate.put("S","s"); + translate.put("T","HH:mm:ss"); + translate.put("U","w"); + translate.put("W","w"); + translate.put("w","E"); + translate.put("y","yy"); + translate.put("Y","yyyy"); + translate.put("z","z"); } + /** + * Initialize this SsiCommand + * + */ public SsiConfig() { - init(); + init(); } - + + /** + * <code>process()</code> should be used since this SsiCommand + * does not return anything. + * + * @param strParamType a value of type 'String[]' + * @param strParam a value of type 'String[]' + * @return a value of type 'String' + */ public String getStream(String[] strParamType, String[] strParam) { - return ""; + return ""; } - + /** * Process request. * @@ -126,34 +158,34 @@ * @param strParam a value of type 'String[]' */ public final void process(String[] strParamType, String[] strParam) { - modified = true; - - for(int i=0;i<strParamType.length;i++) { - if(strParamType[i].equals("errmsg")) - errmsg = strParam[i].getBytes(); - else if(strParamType[i].equals("sizefmt")) - sizefmt = strParam[i]; - else if(strParamType[i].equals("timefmt")) - timefmt = convertFormat(strParam[i]); - } + modified = true; + + for(int i=0;i<strParamType.length;i++) { + if(strParamType[i].equals("errmsg")) + errmsg = strParam[i].getBytes(); + else if(strParamType[i].equals("sizefmt")) + sizefmt = strParam[i]; + else if(strParamType[i].equals("timefmt")) + timefmt = convertFormat(strParam[i]); + } } - + /** * Return the current error message. * * @return a value of type 'byte[]' */ public final byte[] getError() { - return errmsg; + return errmsg; } - + /** * Return the current Size format. * * @return a value of type 'String' */ public final String getSizefmt() { - return sizefmt; + return sizefmt; } /** @@ -162,7 +194,7 @@ * @return a value of type 'String' */ public final String getTimefmt() { - return timefmt; + return timefmt; } /** @@ -170,7 +202,7 @@ * */ public final void flush() { - init(); + init(); } /** @@ -186,64 +218,80 @@ * @return a value of type 'boolean' */ public final boolean isModified() { return modified; } - + + /** + * 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 + */ private String convertFormat(String pattern) { - boolean inside = false; - boolean mark = false; - StringBuffer retString = new StringBuffer(); - String sRetString = ""; - - for(int i = 0; i<pattern.length();i++) { - if(pattern.charAt(i)=='%'&&!mark) { - mark=true; - continue; - } - - if(pattern.charAt(i)=='%'&&mark) { - mark=false; - } - - if(mark) { - if(inside) { - retString.append("'"); - inside=false; - } - - retString.append(translateCommand(pattern.charAt(i))); - mark=false; - continue; - } - - if(!inside) { - retString.append("'"); - inside = true; - } - - retString.append(pattern.charAt(i)); - } - - sRetString = retString.toString(); - - if(!sRetString.endsWith("'")&&inside) - sRetString = sRetString.concat("'"); - - return sRetString; + boolean inside = false; + boolean mark = false; + StringBuffer retString = new StringBuffer(); + String sRetString = ""; + + for(int i = 0; i<pattern.length();i++) { + if(pattern.charAt(i)=='%'&&!mark) { + mark=true; + continue; + } + + if(pattern.charAt(i)=='%'&&mark) { + mark=false; + } + + if(mark) { + if(inside) { + retString.append("'"); + inside=false; + } + + retString.append(translateCommand(pattern.charAt(i))); + mark=false; + continue; + } + + if(!inside) { + retString.append("'"); + inside = true; + } + + retString.append(pattern.charAt(i)); + } + + sRetString = retString.toString(); + + if(!sRetString.endsWith("'")&&inside) + sRetString = sRetString.concat("'"); + + return sRetString; } - + + /** + * 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 + */ private String translateCommand(char c) { - String retCommand = translate.getProperty("".valueOf(c)); - - return retCommand==null?"":retCommand; + String retCommand = translate.getProperty("".valueOf(c)); + + return retCommand==null?"":retCommand; } - + /** - * Called from <code>flush</code>. + * Called from <code>flush</code> Initialize internal parameters + * in their default setting. * */ private void init() { - errmsg = - "[an error occurred while processing this directive]".getBytes(); - sizefmt = "abbrev"; - timefmt = "EEE, dd MMM yyyyy HH:mm:ss z"; + errmsg = + "[an error occurred while processing this directive]".getBytes(); + sizefmt = "abbrev"; + timefmt = "EEE, dd MMM yyyyy HH:mm:ss z"; } } 1.2 +39 -15 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiEcho.java Index: SsiEcho.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiEcho.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiEcho.java 2001/03/27 20:38:00 1.1 +++ SsiEcho.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiEcho.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiEcho.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiEcho.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -65,30 +65,54 @@ package org.apache.catalina.util.ssi; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Return the result associated with the supplied Server Variable. * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class SsiEcho extends SsiMediator implements SsiCommand { - public SsiEcho() {} - + /** + * Get the value associated with this parameter + * + * @param strParamType The parameter type + * @param strParam The value, only "var" accepted + * @return a value The computed result + */ public final String getStream(String[] strParamType, - String[] strParam) { - String retString; + String[] strParam) { + String retString; - if(strParamType[0].equals("var")) - retString = - retString = super.getServerVariable(strParam[0]); - else - retString = new String(super.getError()); + if(strParamType[0].equals("var")) + retString = super.getServerVariable(strParam[0]); + else + retString = new String(super.getError()); - return retString; + return retString; } + /** + * Not used since this SsiCommand return a stream, use + * <code>getStream()</code> instead. + * + * @param strParamType a value of type 'String[]' + * @param strParam a value of type 'String[]' + */ public final void process(String[] strParamType, String[] strParam) {} + + /** + * Returns <code>true</code> this SsiCommand is always prnitable + * and should therefore be accsessed through <code>getStream()</code> + * + * @return a value of type 'boolean' + */ public final boolean isPrintable() { return true; } + /** + * Returns <code>false</code>, this SsiCommands is never buffered. + * + * @return a value of type 'boolean' + */ public final boolean isModified() { return false; } } 1.2 +92 -61 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFlastmod.java Index: SsiFlastmod.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFlastmod.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiFlastmod.java 2001/03/27 20:38:00 1.1 +++ SsiFlastmod.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiFlastmod.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFlastmod.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFlastmod.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -71,76 +71,107 @@ import javax.servlet.ServletContext; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Get the last modified date for a file, the date is subject + * of formatting. * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class SsiFlastmod extends SsiMediator implements SsiCommand { - public SsiFlastmod() {} - + /** + * Get the date of a file and format it correctly + * + * @param strParamType The type of parameter + * @param strParam The value of the parameter + * @return The date of the file + */ public final String getStream(String[] strParamType, - String[] strParam) { - String path = new String(); - long lastModified; - String sLastModified = null; - URL url = null; - - if(strParamType[0].equals("file")) { - path = super.getFilePath(strParam[0]); - } else if(strParamType[0].equals("virtual")) { - path = super.getVirtualPath(strParam[0]); - } - - try { - url = super.servletContext.getResource(path); - lastModified = url.openConnection().getLastModified(); - } catch (MalformedURLException e){ - lastModified = 0; - } catch (IOException e) { - lastModified = 0; - } catch (NullPointerException e) { - lastModified = 0; - } - - if(lastModified==0) - sLastModified = (new String(super.getError())); - else - sLastModified = super.timefmt(new Date(lastModified)); - - return sLastModified; + String[] strParam) { + String path = new String(); + long lastModified; + String sLastModified = null; + URL url = null; + + if(strParamType[0].equals("file")) { + path = super.getFilePath(strParam[0]); + } else if(strParamType[0].equals("virtual")) { + path = super.getVirtualPath(strParam[0]); + } + + try { + url = super.servletContext.getResource(path); + lastModified = url.openConnection().getLastModified(); + } catch (MalformedURLException e){ + lastModified = 0; + } catch (IOException e) { + lastModified = 0; + } catch (NullPointerException e) { + lastModified = 0; + } + + if(lastModified==0) + sLastModified = (new String(super.getError())); + else + sLastModified = super.timefmt(new Date(lastModified)); + + return sLastModified; } - + + /** + * Get the date of a file and format it correctly + * + * @param path The path to the file + * @return The Date to return + */ protected String getDate(String path) { - long lastModified; - String sLastModified = null; - URL url = null; - - path = super.getVirtualPath(path); - - try { - url = super.servletContext.getResource(path); - lastModified = url.openConnection().getLastModified(); - } catch (MalformedURLException e){ - lastModified = 0; - } catch (IOException e) { - lastModified = 0; - } catch (NullPointerException e) { - lastModified = 0; - } - - if(lastModified==0) - sLastModified = (new String(super.getError())); - else - sLastModified = super.timefmt(new Date(lastModified)); - - return sLastModified; + long lastModified; + String sLastModified = null; + URL url = null; + + path = super.getVirtualPath(path); + + try { + url = super.servletContext.getResource(path); + lastModified = url.openConnection().getLastModified(); + } catch (MalformedURLException e){ + lastModified = 0; + } catch (IOException e) { + lastModified = 0; + } catch (NullPointerException e) { + lastModified = 0; + } + + if(lastModified==0) + sLastModified = (new String(super.getError())); + else + sLastModified = super.timefmt(new Date(lastModified)); + + return sLastModified; } - + + /** + * Not used since this SsiCommand return a stream, use + * <code>getStream()</code> instead. + * + * @param strParamType a value of type 'String[]' + * @param strParam a value of type 'String[]' + */ public final void process(String[] strParamType, String[] strParam) {} + /** + * Returns <code>true</code> this SsiCommand is always prnitable + * and should therefore be accsessed through <code>getStream()</code> + * + * @return a value of type 'boolean' + */ public final boolean isPrintable() { return true; } + /** + * Returns <code>false</code>, this SsiCommands is never buffered. + * + * @return a value of type 'boolean' + */ public final boolean isModified() { return false; } } 1.2 +116 -87 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFsize.java Index: SsiFsize.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFsize.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiFsize.java 2001/03/27 20:38:00 1.1 +++ SsiFsize.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiFsize.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFsize.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiFsize.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -70,111 +70,140 @@ import javax.servlet.ServletContext; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * Return the size of a given file, subject of formatting. * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class SsiFsize extends SsiMediator implements SsiCommand { - public SsiFsize() {} - /** * Figure out the length/size of a given file. * - * @param strParamType a value of type 'String[]' - * @param strParam a value of type 'String[]' - * @param req a value of type 'HttpServletRequest' - * @param servletContext a value of type 'ServletContext' - * @return a value of type 'String' + * @param strParamType The parameter type + * @param strParam The value, only "var" accepted + * @return The result */ public final String getStream(String[] strParamType, - String[] strParam) { - String length = ""; - String retLength = ""; - String path = ""; - URL url = null; - long lLength = -1; - - if(strParamType[0].equals("file")) { - path = super.getFilePath(strParam[0]); - } else if(strParamType[0].equals("virtual")) { - path = super.getVirtualPath(strParam[0]); - } - - try { - url = super.servletContext.getResource(path); - lLength = url.openConnection().getContentLength(); - length = (new Long(lLength)).toString(); - } catch (MalformedURLException e){ - length = null; - } catch (IOException e) { - length = null; - } catch (NullPointerException e) { - length = null; - } - - if(length == null) - retLength = (new String(super.getError())); - else - retLength = - formatSize(length, - ((SsiConfig)super.getCommand("config")).getSizefmt()); - - return retLength; + String[] strParam) { + String length = ""; + String retLength = ""; + String path = ""; + URL url = null; + long lLength = -1; + + if(strParamType[0].equals("file")) { + path = super.getFilePath(strParam[0]); + } else if(strParamType[0].equals("virtual")) { + path = super.getVirtualPath(strParam[0]); + } + + try { + url = super.servletContext.getResource(path); + lLength = url.openConnection().getContentLength(); + length = (new Long(lLength)).toString(); + } catch (MalformedURLException e){ + length = null; + } catch (IOException e) { + length = null; + } catch (NullPointerException e) { + length = null; + } + + if(length == null) + retLength = (new String(super.getError())); + else + retLength = + formatSize(length, + ((SsiConfig)super.getCommand("config")).getSizefmt()); + + return retLength; } - + + /** + * Not used since this SsiCommand return a stream, use + * <code>getStream()</code> instead. + * + * @param strParamType a value of type 'String[]' + * @param strParam a value of type 'String[]' + */ public final void process(String[] strParamType, String[] strParam) {} + /** + * Returns <code>true</code> this SsiCommand is always prnitable + * and should therefore be accsessed through <code>getStream()</code> + * + * @return a value of type 'boolean' + */ public final boolean isPrintable() { return true; } + /** + * Returns <code>false</code>, this SsiCommands is never buffered. + * + * @return a value of type 'boolean' + */ public final boolean isModified() { return false; } //----------------- Private methods + /** + * Format the size with the correct format, either + * abbrev or bytes. + * + * @param length The variable to format + * @param format The pattern to use when formatting + * @return The result + */ private String formatSize(String length, String format) { - String retString = ""; - - if(format.equalsIgnoreCase("bytes")) { - retString = commaFormat(length); - } else { - double lParse = (new Long(length)).doubleValue(); - - if(lParse>=1048576) { - double abbrevSize = lParse/1048576; - long splitSize = (long)abbrevSize; - int catSize = (int)(100 * (abbrevSize - splitSize)); - - retString = - commaFormat((new Long(splitSize)).toString())+ - "."+catSize+" MB"; - } else if(lParse>=1024) { - double abbrevSize = lParse/1024; - long splitSize = (long)abbrevSize; - int catSize = (int)(100 * (abbrevSize - splitSize)); - - retString = - commaFormat((new Long(splitSize)).toString())+ - "."+catSize+" KB"; - } else { - retString = - commaFormat(length)+" bytes"; - } - } - - return retString; + String retString = ""; + + if(format.equalsIgnoreCase("bytes")) { + retString = commaFormat(length); + } else { + double lParse = (new Long(length)).doubleValue(); + + if(lParse>=1048576) { + double abbrevSize = lParse/1048576; + long splitSize = (long)abbrevSize; + int catSize = (int)(100 * (abbrevSize - splitSize)); + + retString = + commaFormat((new Long(splitSize)).toString())+ + "."+catSize+" MB"; + } else if(lParse>=1024) { + double abbrevSize = lParse/1024; + long splitSize = (long)abbrevSize; + int catSize = (int)(100 * (abbrevSize - splitSize)); + + retString = + commaFormat((new Long(splitSize)).toString())+ + "."+catSize+" KB"; + } else { + retString = + commaFormat(length)+" bytes"; + } + } + + return retString; } - + + /** + * Modify the supplied variable to be returned comma formated. + * + * @param length The variable to modify + * @return The modified result + */ private String commaFormat(String length) { - String retString = ""; - - for(int i = length.length();i-1>=0;i--) { - retString = (length.substring(i-1,i)).concat(retString); - if((length.length()-(i-1))%3==0&& - retString.length()<length.length()) - retString = ",".concat(retString); - } - - return retString; + String retString = ""; + + for(int i = length.length();i-1>=0;i--) { + retString = (length.substring(i-1,i)).concat(retString); + if((length.length()-(i-1))%3==0&& + retString.length()<length.length()) + retString = ",".concat(retString); + } + + return retString; } } 1.2 +66 -41 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiInclude.java Index: SsiInclude.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiInclude.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SsiInclude.java 2001/03/27 20:38:00 1.1 +++ SsiInclude.java 2001/04/26 22:58:49 1.2 @@ -1,8 +1,8 @@ /* * SsiInclude.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiInclude.java,v 1.1 2001/03/27 20:38:00 amyroh Exp $ - * $Revision: 1.1 $ - * $Date: 2001/03/27 20:38:00 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiInclude.java,v 1.2 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.2 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -71,55 +71,80 @@ import javax.servlet.RequestDispatcher; /** - * @author Bip Thelin - * @version $Revision: 1.1 $, $Date: 2001/03/27 20:38:00 $ + * SsiCommand to include a file, implemented using + * <code>RequestDispatcher.include().</code> * + * @author Bip Thelin + * @version $Revision: 1.2 $, $Date: 2001/04/26 22:58:49 $ */ public final class SsiInclude extends SsiMediator implements SsiCommand { - public SsiInclude() {} - + /** + * Get the stream from the included file. + * + * @param strParamType The parameter type + * @param strParam The file to include + * @return The result from the include + */ public final String getStream(String[] strParamType, - String[] strParam) { - String retString = ""; - String path = ""; - - if(strParamType[0].equals("file")) - path = super.getFilePath(strParam[0]); - else if(strParamType[0].equals("virtual")) - path = super.getVirtualPath(strParam[0]); - - if(path != null) { - try { - if(super.servletContext.getResource(path) != null) { - RequestDispatcher rd = - super.servletContext.getRequestDispatcher(path); - rd.include(super.req, - new ResponseIncludeWrapper(super.res, - (ServletOutputStream)super.out)); - } else{ - retString = new String(super.getError()); - } - } catch (IOException e) { - retString = new String(super.getError()); - } catch (ServletException e) { - retString = new String(super.getError()); - } catch (IllegalArgumentException e) { - retString = new String(super.getError()); - } catch (NullPointerException e) { - retString = new String(super.getError()); - } - } else { - retString = new String(super.getError()); - } - - return retString; + String[] strParam) { + String retString = ""; + String path = ""; + + if(strParamType[0].equals("file")) + path = super.getFilePath(strParam[0]); + else if(strParamType[0].equals("virtual")) + path = super.getVirtualPath(strParam[0]); + + if(path != null) { + try { + if(super.servletContext.getResource(path) != null) { + RequestDispatcher rd = + super.servletContext.getRequestDispatcher(path); + rd.include(super.req, + new ResponseIncludeWrapper(super.res, + (ServletOutputStream)super.out)); + } else{ + retString = new String(super.getError()); + } + } catch (IOException e) { + retString = new String(super.getError()); + } catch (ServletException e) { + retString = new String(super.getError()); + } catch (IllegalArgumentException e) { + retString = new String(super.getError()); + } catch (NullPointerException e) { + retString = new String(super.getError()); + } + } else { + retString = new String(super.getError()); + } + + return retString; } + /** + * Not used since this SsiCommand return a stream, use + * <code>getStream()</code> instead. + * + * @param strParamType a value of type 'String[]' + * @param strParam a value of type 'String[]' + */ public final void process(String[] strParamType, String[] strParam) {} + /** + * Returns <code>true</code> this SsiCommand is always prnitable + * and should therefore be accsessed through <code>getStream()</code> + * + * @return a value of type 'boolean' + */ public final boolean isPrintable() { return true; } + /** + * Returns <code>false</code>, this SsiCommands is never buffered. + * + * @return a value of type 'boolean' + */ public final boolean isModified() { return false; } } 1.4 +326 -234 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiMediator.java Index: SsiMediator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiMediator.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SsiMediator.java 2001/04/03 22:45:33 1.3 +++ SsiMediator.java 2001/04/26 22:58:49 1.4 @@ -1,8 +1,8 @@ /* * SsiMediator.java - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiMediator.java,v 1.3 2001/04/03 22:45:33 amyroh Exp $ - * $Revision: 1.3 $ - * $Date: 2001/04/03 22:45:33 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/ssi/SsiMediator.java,v 1.4 2001/04/26 22:58:49 bip Exp $ + * $Revision: 1.4 $ + * $Date: 2001/04/26 22:58:49 $ * * ==================================================================== * @@ -86,256 +86,345 @@ /** * @author Bip Thelin * @author Amy Roh - * @version $Revision: 1.3 $, $Date: 2001/04/03 22:45:33 $ + * @version $Revision: 1.4 $, $Date: 2001/04/26 22:58:49 $ * */ public class SsiMediator { + /** + * The Servervariables associated with this request + */ protected static Hashtable serverVariables = - new Hashtable(17); + new Hashtable(17); /** * The Commands associated with SSI. */ protected static Hashtable ssiCommands = null; + /** + * The HttpServletResponse associated with this request + */ protected static HttpServletRequest req = null; + /** + * The HttpServletResponse associated with this request. + */ protected static HttpServletResponse res = null; + /** + * The outputStream to use + */ protected static OutputStream out = null; + /** + * The ServletContext associated with this request + */ protected static ServletContext servletContext = null; + /** + * The original ServletContext + */ protected static ServletContext origServletContext = null; + /** + * The contextPath for this request + */ protected static String contextPath = null; + /** + * The relative path for this request + */ protected static String relpath = "/"; + /** + * The path for this request + */ protected static String path = new String(); + /** + * The debug level for this component + */ protected static int debug = 0; + /** + * How this request is being treated + */ protected static boolean isVirtualWebappRelative = false; - public SsiMediator() {} - + /** + * Initialize our pool of SsiCommands + */ static { - ssiCommands = new Hashtable(6); - ssiCommands.put("config", new SsiConfig()); - ssiCommands.put("include", new SsiInclude()); - ssiCommands.put("echo", new SsiEcho()); - ssiCommands.put("fsize", new SsiFsize()); - ssiCommands.put("flastmod", new SsiFlastmod()); - ssiCommands.put("exec", new SsiExec()); + ssiCommands = new Hashtable(6); + ssiCommands.put("config", new SsiConfig()); + ssiCommands.put("include", new SsiInclude()); + ssiCommands.put("echo", new SsiEcho()); + ssiCommands.put("fsize", new SsiFsize()); + ssiCommands.put("flastmod", new SsiFlastmod()); + ssiCommands.put("exec", new SsiExec()); } + public SsiMediator() {} + + /** + * Initialize and set up out enviroment, called from SsiInvokerServlet + * + * @param req The HttpServletRequest to use + * @param res The HttpServletResponse to use + * @param out The OutputStream to use + * @param servletContext The ServletContext to use + * @param path The current path + * @param isVirtualWebappRelative How this request is being treated + */ public SsiMediator(HttpServletRequest req, - HttpServletResponse res, - OutputStream out, - ServletContext servletContext, - int debug, - String path, - boolean isVirtualWebappRelative) { - this.debug = debug; - flush(req, res, out, servletContext, path, isVirtualWebappRelative); + HttpServletResponse res, + OutputStream out, + ServletContext servletContext, + int debug, + String path, + boolean isVirtualWebappRelative) { + this.debug = debug; + flush(req, res, out, servletContext, path, isVirtualWebappRelative); } - + + /** + * Get the SsiCommand + * + * @param cmd The SsiCommand to get + * @return SsiCommand + */ public final SsiCommand getCommand(String cmd) { - return (SsiCommand)ssiCommands.get(cmd); + return (SsiCommand)ssiCommands.get(cmd); } - + + /** + * Initialize and set up out enviroment, called from SsiInvokerServlet + * + * @param req The HttpServletRequest to use + * @param res The HttpServletResponse to use + * @param out The OutputStream to use + * @param servletContext The ServletContext to use + * @param path The current path + * @param isVirtualWebappRelative How this request is being treated + */ public void flush(HttpServletRequest req, - HttpServletResponse res, - OutputStream out, - ServletContext servletContext, - String path, - boolean isVirtualWebappRelative) { - this.req = req; - this.res = res; - this.out = out; - this.servletContext = servletContext; - this.origServletContext = servletContext; - this.contextPath = req.getContextPath(); - this.path = path; - this.relpath = path.substring(0, path.lastIndexOf("/")+1); - this.isVirtualWebappRelative = isVirtualWebappRelative; - int c=0; - - serverVariables.put("AUTH_TYPE", - nullToString(req.getAuthType())); - serverVariables.put("CONTENT_LENGTH", - nullToString(((c=req.getContentLength())<=0)? - null: - (new Integer(c)).toString())); - serverVariables.put("CONTENT_TYPE", - nullToString(req.getContentType())); - serverVariables.put("GATEWAY_INTERFACE", - "CGI/1.1"); - serverVariables.put("PATH_INFO", - nullToString(req.getPathInfo())); - serverVariables.put("PATH_TRANSLATED ", - nullToString(req.getPathTranslated())); - serverVariables.put("QUERY_STRING", - nullToString(req.getQueryString())); - serverVariables.put("REMOTE_ADDR", - nullToString(req.getRemoteAddr())); - serverVariables.put("REMOTE_HOST", - nullToString(req.getRemoteHost())); - serverVariables.put("REMOTE_IDENT", ""); - serverVariables.put("REMOTE_USER", - nullToString(req.getRemoteUser())); - serverVariables.put("REQUEST_METHOD", - nullToString(req.getMethod())); - serverVariables.put("SCRIPT_NAME", - nullToString(req.getServletPath())); - serverVariables.put("SERVER_NAME", - nullToString(req.getServerName())); - serverVariables.put("SERVER_PORT", - (new Integer(req.getServerPort())).toString()); - serverVariables.put("SERVER_PROTOCOL", - nullToString(req.getProtocol())); - serverVariables.put("SERVER_SOFTWARE", - nullToString(servletContext.getServerInfo())); - serverVariables.put("DOCUMENT_NAME", - nullToString(path.substring(path.lastIndexOf("/")+1, - path.length()))); - serverVariables.put("DOCUMENT_URI", - nullToString(path)); - serverVariables.put("QUERY_STRING_UNESCAPED", - nullToString("")); - - flushDate(); - ((SsiConfig)ssiCommands.get("config")).flush(); + HttpServletResponse res, + OutputStream out, + ServletContext servletContext, + String path, + boolean isVirtualWebappRelative) { + this.req = req; + this.res = res; + this.out = out; + this.servletContext = servletContext; + this.origServletContext = servletContext; + this.contextPath = req.getContextPath(); + this.path = path; + this.relpath = path.substring(0, path.lastIndexOf("/")+1); + this.isVirtualWebappRelative = isVirtualWebappRelative; + int c=0; + + serverVariables.put("AUTH_TYPE", + nullToString(req.getAuthType())); + serverVariables.put("CONTENT_LENGTH", + nullToString(((c=req.getContentLength())<=0)? + null: + (new Integer(c)).toString())); + serverVariables.put("CONTENT_TYPE", + nullToString(req.getContentType())); + serverVariables.put("GATEWAY_INTERFACE", + "CGI/1.1"); + serverVariables.put("PATH_INFO", + nullToString(req.getPathInfo())); + serverVariables.put("PATH_TRANSLATED ", + nullToString(req.getPathTranslated())); + serverVariables.put("QUERY_STRING", + nullToString(req.getQueryString())); + serverVariables.put("REMOTE_ADDR", + nullToString(req.getRemoteAddr())); + serverVariables.put("REMOTE_HOST", + nullToString(req.getRemoteHost())); + serverVariables.put("REMOTE_IDENT", ""); + serverVariables.put("REMOTE_USER", + nullToString(req.getRemoteUser())); + serverVariables.put("REQUEST_METHOD", + nullToString(req.getMethod())); + serverVariables.put("SCRIPT_NAME", + nullToString(req.getServletPath())); + serverVariables.put("SERVER_NAME", + nullToString(req.getServerName())); + serverVariables.put("SERVER_PORT", + (new Integer(req.getServerPort())).toString()); + serverVariables.put("SERVER_PROTOCOL", + nullToString(req.getProtocol())); + serverVariables.put("SERVER_SOFTWARE", + nullToString(servletContext.getServerInfo())); + serverVariables.put("DOCUMENT_NAME", + nullToString(path.substring(path.lastIndexOf("/")+1, + path.length()))); + serverVariables.put("DOCUMENT_URI", + nullToString(path)); + serverVariables.put("QUERY_STRING_UNESCAPED", + nullToString("")); + + flushDate(); + ((SsiConfig)ssiCommands.get("config")).flush(); } - + + /** + * Return the current error message + * + * @return The current error message + */ public byte[] getError() { - return ((SsiConfig)ssiCommands.get("config")).getError(); + return ((SsiConfig)ssiCommands.get("config")).getError(); } - + + /** + * Flush the date and make us ready for a new request. + * + */ protected void flushDate() { - serverVariables.put("DATE_LOCAL", - timefmt(new Date())); - serverVariables.put("DATE_GMT", - timefmt(getGMTDate())); - serverVariables.put("LAST_MODIFIED", - ((SsiFlastmod)ssiCommands.get("flastmod")).getDate(path)); + serverVariables.put("DATE_LOCAL", + timefmt(new Date())); + serverVariables.put("DATE_GMT", + timefmt(getGMTDate())); + serverVariables.put("LAST_MODIFIED", + ((SsiFlastmod)ssiCommands.get("flastmod")).getDate(path)); } - + + /** + * Parse a Date according to the current settings. + * + * @param date The date to parse + * @return The parsed date + */ protected String timefmt(Date date) { - String pattern = ((SsiConfig)ssiCommands.get("config")).getTimefmt(); - DateFormat dateFormat = new SimpleDateFormat(pattern, DateTool.LOCALE_US); - - return dateFormat.format(date); + String pattern = ((SsiConfig)ssiCommands.get("config")).getTimefmt(); + DateFormat dateFormat = new SimpleDateFormat(pattern, DateTool.LOCALE_US); + + return dateFormat.format(date); } - + + /** + * Parse a Date according to the current settings. + * + * @param date The date to parse + * @return The parsed date + */ protected String timefmt(String date) { - DateFormat dateFormat = DateFormat.getDateTimeInstance(); - Date parsedDate = null; - - try { - parsedDate = dateFormat.parse(date); - } catch (ParseException e) { - return new String(getError()); - } - - return timefmt(parsedDate); + DateFormat dateFormat = DateFormat.getDateTimeInstance(); + Date parsedDate = null; + + try { + parsedDate = dateFormat.parse(date); + } catch (ParseException e) { + return new String(getError()); + } + + return timefmt(parsedDate); } - + + /** + * Get a server variable + * + * @param serverVar The server variable to get + * @return The parsed result + */ protected String getServerVariable(String serverVar) { - flushDate(); - - if(serverVariables.get(serverVar)==null) - return new String(getError()); - else - return (String)serverVariables.get(serverVar); + flushDate(); + + if(serverVariables.get(serverVar)==null) + return new String(getError()); + else + return (String)serverVariables.get(serverVar); } - + + /** + * Return a path relative to either the webapp or the root("/") + * + * Example of valid paths: + * "/test/path/test.file" + * "../test/path/test.file" + * + * @param path Path to be normalized + */ protected String getVirtualPath(String path) { if (path == null) return null; - + // Create a place for the normalized path String normalized = path; - - /* - * Commented out -- already URL-decoded in StandardContextMapper - * Decoding twice leaves the container vulnerable to %25 --> '%' - * attacks. - * - * if (normalized.indexOf('%') >= 0) - * normalized = RequestUtil.URLDecode(normalized, "UTF8"); - */ - + if (normalized == null) return (null); - - // Normalize the slashes and add leading slash if necessary - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); - if (!normalized.startsWith("/")) - normalized = relpath.concat(normalized); - - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); - } - - // Resolve occurrences of "/./" in the normalized path - while (true) { - int index = normalized.indexOf("/./"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 2); - } - - // Resolve occurrences of "/../" in the normalized path - while (true) { - int index = normalized.indexOf("/../"); - if (index < 0) - break; - if (index == 0) - return (null); // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); - } - - if (!isVirtualWebappRelative) { - // case of virtual="file.txt", "./file.txt", or dir/file.txt - if ((!path.startsWith("/")) || (path.startsWith("./"))) { - // handle as file in the current directory with original servletContext - servletContext = origServletContext; - }else if (path.indexOf("/", 1)==-1) { - //root context - servletContext = servletContext.getContext("/"); - } else if (!contextPath.equals("")) { - //starts with the context path of this webapp - if ((normalized !=null) && (normalized.startsWith(contextPath))) { - // strip off the context path - servletContext = servletContext.getContext(contextPath); - normalized = normalized.substring(contextPath.length()); - } - } else if (normalized != null){ - // find which context is the right one to handle - String context = normalized.substring(0, path.indexOf("/", 1)); - ServletContext sc = servletContext.getContext(context); - if (sc!=null) { - servletContext = sc; - normalized = normalized.substring(context.length()); + + // Normalize the slashes and add leading slash if necessary + if (normalized.indexOf('\\') >= 0) + normalized = normalized.replace('\\', '/'); + if (!normalized.startsWith("/")) + normalized = relpath.concat(normalized); + + // Resolve occurrences of "//" in the normalized path + while (true) { + int index = normalized.indexOf("//"); + if (index < 0) + break; + normalized = normalized.substring(0, index) + + normalized.substring(index + 1); + } + + // Resolve occurrences of "/./" in the normalized path + while (true) { + int index = normalized.indexOf("/./"); + if (index < 0) + break; + normalized = normalized.substring(0, index) + + normalized.substring(index + 2); + } + + // Resolve occurrences of "/../" in the normalized path + while (true) { + int index = normalized.indexOf("/../"); + if (index < 0) + break; + if (index == 0) + return (null); // Trying to go outside our context + int index2 = normalized.lastIndexOf('/', index - 1); + normalized = normalized.substring(0, index2) + + normalized.substring(index + 3); + } + + if (!isVirtualWebappRelative) { + // case of virtual="file.txt", "./file.txt", or dir/file.txt + if ((!path.startsWith("/")) || (path.startsWith("./"))) { + // handle as file in the current directory with original servletContext + servletContext = origServletContext; + }else if (path.indexOf("/", 1)==-1) { + //root context + servletContext = servletContext.getContext("/"); + } else if (!contextPath.equals("")) { + //starts with the context path of this webapp + if ((normalized !=null) && (normalized.startsWith(contextPath))) { + // strip off the context path + servletContext = servletContext.getContext(contextPath); + normalized = normalized.substring(contextPath.length()); + } + } else if (normalized != null){ + // find which context is the right one to handle + String context = normalized.substring(0, path.indexOf("/", 1)); + ServletContext sc = servletContext.getContext(context); + if (sc!=null) { + servletContext = sc; + normalized = normalized.substring(context.length()); + } } } - } - - return (normalized); + + return (normalized); } - + /** * Return a path relative to the file being parsed, if they * try to use "../" or have a trailing "/" we return @@ -350,54 +439,57 @@ protected String getFilePath(String path) { if (path == null) return null; - + // Create a place for the normalized path String normalized = path; - - /* - * Commented out -- already URL-decoded in StandardContextMapper - * Decoding twice leaves the container vulnerable to %25 --> '%' - * attacks. - * - * if (normalized.indexOf('%') >= 0) - * normalized = RequestUtil.URLDecode(normalized, "UTF8"); - */ - - servletContext = origServletContext; - + + servletContext = origServletContext; + if (normalized == null) return (null); - - // Normalize the slashes - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); - - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); - } - - // If it starts with a "/" or contains "../" we return <code>null</code>. - if (normalized.startsWith("/") || normalized.indexOf("../") >= 0) - return (null); - - // Return the normalized path that we have completed - return (relpath.concat(normalized)); + + // Normalize the slashes + if (normalized.indexOf('\\') >= 0) + normalized = normalized.replace('\\', '/'); + + // Resolve occurrences of "//" in the normalized path + while (true) { + int index = normalized.indexOf("//"); + if (index < 0) + break; + normalized = normalized.substring(0, index) + + normalized.substring(index + 1); + } + + // If it starts with a "/" or contains "../" we return <code>null</code>. + if (normalized.startsWith("/") || normalized.indexOf("../") >= 0) + return (null); + + // Return the normalized path that we have completed + return (relpath.concat(normalized)); } - + + /** + * Check if the supplied string is <code>null</code> and + * if so return an empty string. + * + * @param s a value of type 'String' + * @return a value of type 'String' + */ private String nullToString(String s) { - return s==null?"":s; + return s==null?"":s; } - + + /** + * Get the current Date GMT formated. + * + * @return The current GMT formatted date. + */ private String getGMTDate() { - Date date = new Date(); - DateFormat dateFormat = DateFormat.getDateTimeInstance(); - - dateFormat.setTimeZone(DateTool.GMT_ZONE); - return dateFormat.format(date); + Date date = new Date(); + DateFormat dateFormat = DateFormat.getDateTimeInstance(); + + dateFormat.setTimeZone(DateTool.GMT_ZONE); + return dateFormat.format(date); } }