org.apache.catalina.util.IOTools Java Examples

The following examples show how to use org.apache.catalina.util.IOTools. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractCatalinaTask.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
private void preAuthenticate() throws IOException {
    URLConnection conn = null;

    // Create a connection for this command
    conn = (new URL(url)).openConnection();
    HttpURLConnection hconn = (HttpURLConnection) conn;

    // Set up standard connection characteristics
    hconn.setAllowUserInteraction(false);
    hconn.setDoInput(true);
    hconn.setUseCaches(false);
    hconn.setDoOutput(false);
    hconn.setRequestMethod("OPTIONS");
    hconn.setRequestProperty("User-Agent", "Catalina-Ant-Task/1.0");

    // Establish the connection with the server
    hconn.connect();

    // Swallow response message
    IOTools.flow(hconn.getInputStream(), null);
}
 
Example #2
Source File: TestStandardContextResources.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

    resp.setContentType("text/plain");

    ServletContext context = getServletContext();

    // Check resources individually
    URL url = context.getResource(req.getParameter("path"));
    if (url == null) {
        resp.getWriter().println("Not found");
        return;
    }

    try (InputStream input = url.openStream();
            OutputStream output = resp.getOutputStream()) {
        IOTools.flow(input, output);
    }
}
 
Example #3
Source File: Http2TestBase.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    // Do not do this at home. The unconstrained buffer is a DoS risk.

    // Have to read into a buffer because clients typically do not start
    // to read the response until the request is fully written.
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    IOTools.flow(req.getInputStream(), baos);

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    IOTools.flow(bais, resp.getOutputStream());

    // Check for trailer headers
    String trailerValue = req.getHeader(TRAILER_HEADER_NAME);
    if (trailerValue != null) {
        resp.getOutputStream().write(trailerValue.getBytes(StandardCharsets.UTF_8));
    }
}
 
Example #4
Source File: TestAbstractInputStreamJar.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Test
public void testNestedJarGetInputStream() throws Exception {
    File f = new File("test/webresources/war-url-connection.war");
    StringBuilder sb = new StringBuilder("war:");
    sb.append(f.toURI().toURL());
    sb.append("*/WEB-INF/lib/test.jar");

    Jar jar = JarFactory.newInstance(new URL(sb.toString()));

    InputStream is1 = jar.getInputStream("META-INF/resources/index.html");
    ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
    IOTools.flow(is1, baos1);

    InputStream is2 = jar.getInputStream("META-INF/resources/index.html");
    ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
    IOTools.flow(is2, baos2);

    Assert.assertArrayEquals(baos1.toByteArray(), baos2.toByteArray());
}
 
Example #5
Source File: TestFlushableGZIPOutputStream.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
/**
 * Writes data to the stream and returns the size of the file.
 */
private void flowBytes(byte[] bytes, OutputStream output)
        throws IOException {
    // Could use output.write(), but IOTools writes in small portions, and
    // that is more natural
    ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
    try {
        IOTools.flow(byteInStream, output);
    } finally {
        byteInStream.close();
    }
}
 
Example #6
Source File: Tomcat.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
/**
 * Copy the specified WAR file to the Host's appBase and then call
 * {@link #addWebapp(String, String)} with the newly copied WAR. The WAR
 * will <b>NOT</b> be removed from the Host's appBase when the Tomcat
 * instance stops. Note that {@link ExpandWar} provides utility methods that
 * may be used to delete the WAR and/or expanded directory if required.
 *
 * @param contextPath   The context mapping to use, "" for root context.
 * @param source        The location from which the WAR should be copied
 *
 * @return The deployed Context
 *
 * @throws IOException If an I/O error occurs while copying the WAR file
 *                     from the specified URL to the appBase
 */
public Context addWebapp(String contextPath, URL source) throws IOException {

    ContextName cn = new ContextName(contextPath, null);

    // Make sure a conflicting web application has not already been deployed
    Host h = getHost();
    if (h.findChild(cn.getName()) != null) {
        throw new IllegalArgumentException(sm.getString("tomcat.addWebapp.conflictChild",
                source, contextPath, cn.getName()));
    }

    // Make sure appBase does not contain a conflicting web application
    File targetWar = new File(h.getAppBaseFile(), cn.getBaseName() + ".war");
    File targetDir = new File(h.getAppBaseFile(), cn.getBaseName());

    if (targetWar.exists()) {
        throw new IllegalArgumentException(sm.getString("tomcat.addWebapp.conflictFile",
                source, contextPath, targetWar.getAbsolutePath()));
    }
    if (targetDir.exists()) {
        throw new IllegalArgumentException(sm.getString("tomcat.addWebapp.conflictFile",
                source, contextPath, targetDir.getAbsolutePath()));
    }

    // Should be good to copy the WAR now
    URLConnection uConn = source.openConnection();

    try (InputStream is = uConn.getInputStream();
            OutputStream os = new FileOutputStream(targetWar)) {
        IOTools.flow(is, os);
    }

    return addWebapp(contextPath, targetWar.getAbsolutePath());
}
 
Example #7
Source File: TestFlushableGZIPOutputStream.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
/**
 * Loads file into memory.
 */
private byte[] loadFile(File file) throws IOException {
    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    FileInputStream input = new FileInputStream(file);
    try {
        IOTools.flow(input, byteOutStream);
    } finally {
        input.close();
    }
    return byteOutStream.toByteArray();
}
 
Example #8
Source File: TestFlushableGZIPOutputStream.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
/**
 * Test for {@code write(int)}.
 */
@Test
public void testWriteChar() throws Exception {
    String phrase = "Apache Tomcat "
            + "\u0410\u043f\u0430\u0447\u0435 \u0422\u043e\u043c\u043a\u0430\u0442 ";
    byte[] data = phrase.getBytes("UTF-8");

    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    OutputStream output = new FlushableGZIPOutputStream(byteOutStream);

    output.write(data);
    for (int i=0; i<data.length; i++) {
        output.write(data[i]);
    }
    output.flush();
    for (int i=0; i<data.length; i++) {
        output.write(data[i]);
    }
    output.write(data);
    output.close();

    ByteArrayInputStream byteInStream =
            new ByteArrayInputStream(byteOutStream.toByteArray());

    GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream);
    ByteArrayOutputStream sink = new ByteArrayOutputStream();
    try {
        IOTools.flow(inflaterStream, sink);
    } finally {
        sink.close();
    }

    byte[] decompressedBytes = sink.toByteArray();
    assertEquals(data.length * 4, decompressedBytes.length);
    for (int i = 0; i < 4; i++) {
        assertArrayEquals(data, Arrays.copyOfRange(decompressedBytes,
                data.length * i, data.length * (i + 1)));
    }
}
 
Example #9
Source File: TestFlushableGZIPOutputStream.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
/**
 * Writes data to the stream and returns the size of the file.
 */
private void flowBytes(byte[] bytes, OutputStream output)
        throws IOException {
    // Could use output.write(), but IOTools writes in small portions, and
    // that is more natural
    ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
    try {
        IOTools.flow(byteInStream, output);
    } finally {
        byteInStream.close();
    }
}
 
Example #10
Source File: TestFlushableGZIPOutputStream.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
/**
 * Loads file into memory.
 */
private byte[] loadFile(File file) throws IOException {
    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    FileInputStream input = new FileInputStream(file);
    try {
        IOTools.flow(input, byteOutStream);
    } finally {
        input.close();
    }
    return byteOutStream.toByteArray();
}
 
Example #11
Source File: TestFlushableGZIPOutputStream.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
/**
 * Test for {@code write(int)}.
 */
@Test
public void testWriteChar() throws Exception {
    String phrase = "Apache Tomcat "
            + "\u0410\u043f\u0430\u0447\u0435 \u0422\u043e\u043c\u043a\u0430\u0442 ";
    byte[] data = phrase.getBytes("UTF-8");

    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    OutputStream output = new FlushableGZIPOutputStream(byteOutStream);

    output.write(data);
    for (int i=0; i<data.length; i++) {
        output.write(data[i]);
    }
    output.flush();
    for (int i=0; i<data.length; i++) {
        output.write(data[i]);
    }
    output.write(data);
    output.close();

    ByteArrayInputStream byteInStream =
            new ByteArrayInputStream(byteOutStream.toByteArray());

    GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream);
    ByteArrayOutputStream sink = new ByteArrayOutputStream();
    try {
        IOTools.flow(inflaterStream, sink);
    } finally {
        sink.close();
    }

    byte[] decompressedBytes = sink.toByteArray();
    assertEquals(data.length * 4, decompressedBytes.length);
    for (int i = 0; i < 4; i++) {
        assertArrayEquals(data, Arrays.copyOfRange(decompressedBytes,
                data.length * i, data.length * (i + 1)));
    }
}
 
Example #12
Source File: TesterOpenSSL.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
@Override
public void run() {
    try {
        IOTools.flow(is, baos);
    } catch (IOException e) {
        // Ignore
    }
}
 
Example #13
Source File: TomcatBaseTest.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    // Beware of clients that try to send the whole request body before
    // reading any of the response. They may cause this test to lock up.
    try (InputStream is = req.getInputStream();
            OutputStream os = resp.getOutputStream()) {
        IOTools.flow(is, os);
    }
}
 
Example #14
Source File: ExtractingRoot.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
@Override
protected void processWebInfLib() throws LifecycleException {

    // Don't extract JAR files unless the application is deployed as a
    // packed WAR file.
    if (!super.isPackedWarFile()) {
        super.processWebInfLib();
        return;
    }

    File expansionTarget = getExpansionTarget();
    if (!expansionTarget.isDirectory()) {
        if (!expansionTarget.mkdirs()) {
            throw new LifecycleException(
                    sm.getString("extractingRoot.targetFailed", expansionTarget));
        }
    }

    WebResource[] possibleJars = listResources("/WEB-INF/lib", false);

    for (WebResource possibleJar : possibleJars) {
        if (possibleJar.isFile() && possibleJar.getName().endsWith(".jar")) {
            try {
                File dest = new File(expansionTarget, possibleJar.getName());
                dest = dest.getCanonicalFile();
                try (InputStream sourceStream = possibleJar.getInputStream();
                        OutputStream destStream= new FileOutputStream(dest)) {
                    IOTools.flow(sourceStream, destStream);
                }

                createWebResourceSet(ResourceSetType.CLASSES_JAR,
                        "/WEB-INF/classes", dest.toURI().toURL(), "/");
            } catch (IOException ioe) {
                throw new LifecycleException(
                        sm.getString("extractingRoot.jarFailed", possibleJar.getName()), ioe);
            }
        }
    }
}
 
Example #15
Source File: TestFlushableGZIPOutputStream.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
@Test
public void testBug52121() throws Exception {

    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    OutputStream output = new FlushableGZIPOutputStream(byteOutStream);

    File sourcesDir = new File("test/org/apache/coyote/http11/filters/");
    List<byte[]> parts = new ArrayList<byte[]>();
    byte[] part;

    part = loadFile(new File(sourcesDir, "bug52121-part1"));
    parts.add(part);
    flowBytes(part, output);
    output.flush();

    part = loadFile(new File(sourcesDir, "bug52121-part2"));
    parts.add(part);
    flowBytes(part, output);
    output.flush();

    part = "data2".getBytes("ASCII");
    parts.add(part);
    output.write(part);
    output.flush();

    output.close();

    ByteArrayInputStream byteInStream =
            new ByteArrayInputStream(byteOutStream.toByteArray());

    GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream);
    ByteArrayOutputStream sink = new ByteArrayOutputStream();
    try {
        IOTools.flow(inflaterStream, sink);
    } finally {
        sink.close();
    }

    byte[] decompressedBytes = sink.toByteArray();
    int originalLength = 0;
    for (byte[] bytes : parts) {
        assertArrayEquals(bytes, Arrays.copyOfRange(decompressedBytes,
                originalLength, originalLength + bytes.length));
        originalLength += bytes.length;
    }
    assertEquals(originalLength, decompressedBytes.length);
}
 
Example #16
Source File: SSIProcessor.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Process a file with server-side commands, reading from reader and
 * writing the processed version to writer. NOTE: We really should be doing
 * this in a streaming way rather than converting it to an array first.
 * 
 * @param reader
 *            the reader to read the file containing SSIs from
 * @param writer
 *            the writer to write the file with the SSIs processed.
 * @return the most current modified date resulting from any SSI commands
 * @throws IOException
 *             when things go horribly awry. Should be unlikely since the
 *             SSICommand usually catches 'normal' IOExceptions.
 */
public long process(Reader reader, long lastModifiedDate,
        PrintWriter writer) throws IOException {
    SSIMediator ssiMediator = new SSIMediator(ssiExternalResolver,
            lastModifiedDate, debug);
    StringWriter stringWriter = new StringWriter();
    IOTools.flow(reader, stringWriter);
    String fileContents = stringWriter.toString();
    stringWriter = null;
    int index = 0;
    boolean inside = false;
    StringBuilder command = new StringBuilder();
    try {
        while (index < fileContents.length()) {
            char c = fileContents.charAt(index);
            if (!inside) {
                if (c == COMMAND_START.charAt(0)
                        && charCmp(fileContents, index, COMMAND_START)) {
                    inside = true;
                    index += COMMAND_START.length();
                    command.setLength(0); //clear the command string
                } else {
                    if (!ssiMediator.getConditionalState().processConditionalCommandsOnly) {
                        writer.write(c);
                    }
                    index++;
                }
            } else {
                if (c == COMMAND_END.charAt(0)
                        && charCmp(fileContents, index, COMMAND_END)) {
                    inside = false;
                    index += COMMAND_END.length();
                    String strCmd = parseCmd(command);
                    if (debug > 0) {
                        ssiExternalResolver.log(
                                "SSIProcessor.process -- processing command: "
                                        + strCmd, null);
                    }
                    String[] paramNames = parseParamNames(command, strCmd
                            .length());
                    String[] paramValues = parseParamValues(command,
                            strCmd.length(), paramNames.length);
                    //We need to fetch this value each time, since it may
                    // change
                    // during the loop
                    String configErrMsg = ssiMediator.getConfigErrMsg();
                    SSICommand ssiCommand =
                        commands.get(strCmd.toLowerCase(Locale.ENGLISH));
                    String errorMessage = null;
                    if (ssiCommand == null) {
                        errorMessage = "Unknown command: " + strCmd;
                    } else if (paramValues == null) {
                        errorMessage = "Error parsing directive parameters.";
                    } else if (paramNames.length != paramValues.length) {
                        errorMessage = "Parameter names count does not match parameter values count on command: "
                                + strCmd;
                    } else {
                        // don't process the command if we are processing
                        // conditional
                        // commands only and the
                        // command is not conditional
                        if (!ssiMediator.getConditionalState().processConditionalCommandsOnly
                                || ssiCommand instanceof SSIConditional) {
                            long lmd = ssiCommand.process(ssiMediator, strCmd,
                                           paramNames, paramValues, writer);
                            if (lmd > lastModifiedDate) {
                                lastModifiedDate = lmd;
                            }                                    
                        }
                    }
                    if (errorMessage != null) {
                        ssiExternalResolver.log(errorMessage, null);
                        writer.write(configErrMsg);
                    }
                } else {
                    command.append(c);
                    index++;
                }
            }
        }
    } catch (SSIStopProcessingException e) {
        //If we are here, then we have already stopped processing, so all
        // is good
    }
    return lastModifiedDate;
}
 
Example #17
Source File: SSIProcessor.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Process a file with server-side commands, reading from reader and
 * writing the processed version to writer. NOTE: We really should be doing
 * this in a streaming way rather than converting it to an array first.
 * 
 * @param reader
 *            the reader to read the file containing SSIs from
 * @param writer
 *            the writer to write the file with the SSIs processed.
 * @return the most current modified date resulting from any SSI commands
 * @throws IOException
 *             when things go horribly awry. Should be unlikely since the
 *             SSICommand usually catches 'normal' IOExceptions.
 */
public long process(Reader reader, long lastModifiedDate,
        PrintWriter writer) throws IOException {
    SSIMediator ssiMediator = new SSIMediator(ssiExternalResolver,
            lastModifiedDate, debug);
    StringWriter stringWriter = new StringWriter();
    IOTools.flow(reader, stringWriter);
    String fileContents = stringWriter.toString();
    stringWriter = null;
    int index = 0;
    boolean inside = false;
    StringBuilder command = new StringBuilder();
    try {
        while (index < fileContents.length()) {
            char c = fileContents.charAt(index);
            if (!inside) {
                if (c == COMMAND_START.charAt(0)
                        && charCmp(fileContents, index, COMMAND_START)) {
                    inside = true;
                    index += COMMAND_START.length();
                    command.setLength(0); //clear the command string
                } else {
                    if (!ssiMediator.getConditionalState().processConditionalCommandsOnly) {
                        writer.write(c);
                    }
                    index++;
                }
            } else {
                if (c == COMMAND_END.charAt(0)
                        && charCmp(fileContents, index, COMMAND_END)) {
                    inside = false;
                    index += COMMAND_END.length();
                    String strCmd = parseCmd(command);
                    if (debug > 0) {
                        ssiExternalResolver.log(
                                "SSIProcessor.process -- processing command: "
                                        + strCmd, null);
                    }
                    String[] paramNames = parseParamNames(command, strCmd
                            .length());
                    String[] paramValues = parseParamValues(command,
                            strCmd.length(), paramNames.length);
                    //We need to fetch this value each time, since it may
                    // change
                    // during the loop
                    String configErrMsg = ssiMediator.getConfigErrMsg();
                    SSICommand ssiCommand =
                        commands.get(strCmd.toLowerCase(Locale.ENGLISH));
                    String errorMessage = null;
                    if (ssiCommand == null) {
                        errorMessage = "Unknown command: " + strCmd;
                    } else if (paramValues == null) {
                        errorMessage = "Error parsing directive parameters.";
                    } else if (paramNames.length != paramValues.length) {
                        errorMessage = "Parameter names count does not match parameter values count on command: "
                                + strCmd;
                    } else {
                        // don't process the command if we are processing
                        // conditional
                        // commands only and the
                        // command is not conditional
                        if (!ssiMediator.getConditionalState().processConditionalCommandsOnly
                                || ssiCommand instanceof SSIConditional) {
                            long lmd = ssiCommand.process(ssiMediator, strCmd,
                                           paramNames, paramValues, writer);
                            if (lmd > lastModifiedDate) {
                                lastModifiedDate = lmd;
                            }                                    
                        }
                    }
                    if (errorMessage != null) {
                        ssiExternalResolver.log(errorMessage, null);
                        writer.write(configErrMsg);
                    }
                } else {
                    command.append(c);
                    index++;
                }
            }
        }
    } catch (SSIStopProcessingException e) {
        //If we are here, then we have already stopped processing, so all
        // is good
    }
    return lastModifiedDate;
}
 
Example #18
Source File: TestFlushableGZIPOutputStream.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
@Test
public void testBug52121() throws Exception {

    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    OutputStream output = new FlushableGZIPOutputStream(byteOutStream);

    File sourcesDir = new File("test/org/apache/coyote/http11/filters/");
    List<byte[]> parts = new ArrayList<byte[]>();
    byte[] part;

    part = loadFile(new File(sourcesDir, "bug52121-part1"));
    parts.add(part);
    flowBytes(part, output);
    output.flush();

    part = loadFile(new File(sourcesDir, "bug52121-part2"));
    parts.add(part);
    flowBytes(part, output);
    output.flush();

    part = "data2".getBytes("ASCII");
    parts.add(part);
    output.write(part);
    output.flush();

    output.close();

    ByteArrayInputStream byteInStream =
            new ByteArrayInputStream(byteOutStream.toByteArray());

    GZIPInputStream inflaterStream = new GZIPInputStream(byteInStream);
    ByteArrayOutputStream sink = new ByteArrayOutputStream();
    try {
        IOTools.flow(inflaterStream, sink);
    } finally {
        sink.close();
    }

    byte[] decompressedBytes = sink.toByteArray();
    int originalLength = 0;
    for (byte[] bytes : parts) {
        assertArrayEquals(bytes, Arrays.copyOfRange(decompressedBytes,
                originalLength, originalLength + bytes.length));
        originalLength += bytes.length;
    }
    assertEquals(originalLength, decompressedBytes.length);
}
 
Example #19
Source File: SSIProcessor.java    From Tomcat8-Source-Read with MIT License 4 votes vote down vote up
/**
 * Process a file with server-side commands, reading from reader and
 * writing the processed version to writer. NOTE: We really should be doing
 * this in a streaming way rather than converting it to an array first.
 *
 * @param reader
 *            the reader to read the file containing SSIs from
 * @param lastModifiedDate resource last modification date
 * @param writer
 *            the writer to write the file with the SSIs processed.
 * @return the most current modified date resulting from any SSI commands
 * @throws IOException
 *             when things go horribly awry. Should be unlikely since the
 *             SSICommand usually catches 'normal' IOExceptions.
 */
public long process(Reader reader, long lastModifiedDate,
        PrintWriter writer) throws IOException {
    SSIMediator ssiMediator = new SSIMediator(ssiExternalResolver,
            lastModifiedDate);
    StringWriter stringWriter = new StringWriter();
    IOTools.flow(reader, stringWriter);
    String fileContents = stringWriter.toString();
    stringWriter = null;
    int index = 0;
    boolean inside = false;
    StringBuilder command = new StringBuilder();
    try {
        while (index < fileContents.length()) {
            char c = fileContents.charAt(index);
            if (!inside) {
                if (c == COMMAND_START.charAt(0)
                        && charCmp(fileContents, index, COMMAND_START)) {
                    inside = true;
                    index += COMMAND_START.length();
                    command.setLength(0); //clear the command string
                } else {
                    if (!ssiMediator.getConditionalState().processConditionalCommandsOnly) {
                        writer.write(c);
                    }
                    index++;
                }
            } else {
                if (c == COMMAND_END.charAt(0)
                        && charCmp(fileContents, index, COMMAND_END)) {
                    inside = false;
                    index += COMMAND_END.length();
                    String strCmd = parseCmd(command);
                    if (debug > 0) {
                        ssiExternalResolver.log(
                                "SSIProcessor.process -- processing command: "
                                        + strCmd, null);
                    }
                    String[] paramNames = parseParamNames(command, strCmd
                            .length());
                    String[] paramValues = parseParamValues(command,
                            strCmd.length(), paramNames.length);
                    //We need to fetch this value each time, since it may
                    // change
                    // during the loop
                    String configErrMsg = ssiMediator.getConfigErrMsg();
                    SSICommand ssiCommand =
                        commands.get(strCmd.toLowerCase(Locale.ENGLISH));
                    String errorMessage = null;
                    if (ssiCommand == null) {
                        errorMessage = "Unknown command: " + strCmd;
                    } else if (paramValues == null) {
                        errorMessage = "Error parsing directive parameters.";
                    } else if (paramNames.length != paramValues.length) {
                        errorMessage = "Parameter names count does not match parameter values count on command: "
                                + strCmd;
                    } else {
                        // don't process the command if we are processing
                        // conditional
                        // commands only and the
                        // command is not conditional
                        if (!ssiMediator.getConditionalState().processConditionalCommandsOnly
                                || ssiCommand instanceof SSIConditional) {
                            long lmd = ssiCommand.process(ssiMediator, strCmd,
                                           paramNames, paramValues, writer);
                            if (lmd > lastModifiedDate) {
                                lastModifiedDate = lmd;
                            }
                        }
                    }
                    if (errorMessage != null) {
                        ssiExternalResolver.log(errorMessage, null);
                        writer.write(configErrMsg);
                    }
                } else {
                    command.append(c);
                    index++;
                }
            }
        }
    } catch (SSIStopProcessingException e) {
        //If we are here, then we have already stopped processing, so all
        // is good
    }
    return lastModifiedDate;
}