--- /dev/null
+/*
+ */
+package org.apache.coyote.lite;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import junit.framework.TestCase;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.coyote.lite.LiteProtocolHandler;
+import org.apache.tomcat.lite.http.DefaultHttpConnector;
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnector;
+import org.apache.tomcat.lite.io.BBuffer;
+
+public class TomcatLiteCoyoteTest extends TestCase {
+
+ static Tomcat tomcat;
+ LiteProtocolHandler litePH;
+
+ public void setUp() {
+ if (tomcat == null) {
+ try {
+ tomcat = new Tomcat();
+ tomcat.setPort(8885);
+ tomcat.setBaseDir("output/build");
+
+ tomcat.addWebapp("/examples", "examples");
+ tomcat.addWebapp("/", "ROOT");
+
+
+ //tomcat.addServlet(ctx, "name", "class");
+ // ctx.addServletMapping("/foo/*", "name");
+
+ litePH = setUp(tomcat);
+
+ tomcat.start();
+ } catch (LifecycleException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ServletException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static LiteProtocolHandler setUp(Tomcat tomcat) {
+ Connector connector = new Connector(LiteProtocolHandler.class.getName());
+ tomcat.getService().addConnector(connector);
+ connector.setPort(8885);
+ tomcat.setConnector(connector);
+ LiteProtocolHandler ph =
+ (LiteProtocolHandler) connector.getProtocolHandler();
+ return ph;
+ }
+
+
+ public void testSimple() throws IOException {
+ HttpConnector clientCon = DefaultHttpConnector.get();
+ HttpChannel ch = clientCon.get("localhost", 8885);
+ ch.getRequest().setRequestURI("/examples/servlets/servlet/HelloWorldExample");
+ ch.sendRequest();
+ BBuffer res = ch.readAll(null, 0);
+
+ assertTrue(res.toString().indexOf("<title>Hello World!</title>") >= 0);
+ }
+
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.coyote.servlet;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.coyote.OutputBuffer;
+import org.apache.coyote.Response;
+import org.apache.tomcat.lite.SimpleServlet;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class LiteTestHelper {
+
+ public static void addContext(TomcatLite lite) throws ServletException {
+ ServletContextImpl ctx =
+ (ServletContextImpl) lite.addServletContext(null, null, "/test1");
+
+ ctx.addServlet("test", new SimpleServlet());
+ ctx.addMapping("/1stTest", "test");
+
+ ctx.addServlet("testException", new HttpServlet() {
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws IOException {
+ throw new NullPointerException();
+ }
+ });
+ ctx.addMapping("/testException", "testException");
+ }
+
+ public static void initServletsAndRun(TomcatLite lite, int port) throws ServletException, IOException {
+ addContext(lite);
+ lite.init();
+ lite.start();
+
+
+ if (port > 0) {
+ // This should be added after all local initialization to avoid
+ // the server from responding.
+ // Alternatively, you can load this early but set it to return
+ // 'unavailable' if load balancers depend on this.
+ addConnector(lite, port, true);
+
+ // At this point we can add contexts and inject requests, if we want to
+ // do it over HTTP need to start the connector as well.
+ lite.startConnector();
+ }
+ }
+
+ public static void addConnector(TomcatLite lite,
+ int port, boolean daemon) {
+ CoyoteConnector coyoteAdapter = (CoyoteConnector) lite.getConnector();
+ coyoteAdapter.setPort(port);
+ coyoteAdapter.setDaemon(daemon);
+ }
+
+ /**
+ * Get url using URLConnection.
+ */
+ public static ByteChunk getUrl(String path) throws IOException {
+
+ ByteChunk out = new ByteChunk();
+
+ URL url = new URL(path);
+ URLConnection connection = url.openConnection();
+ connection.setReadTimeout(5000);
+ connection.connect();
+ InputStream is = connection.getInputStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ byte[] buf = new byte[2048];
+ int rd = 0;
+ while((rd = bis.read(buf)) > 0) {
+ out.append(buf, 0, rd);
+ }
+ return out;
+ }
+
+ static class ByteChunkOutputBuffer implements OutputBuffer {
+
+ protected ByteChunk output = null;
+
+ public ByteChunkOutputBuffer(ByteChunk output) {
+ this.output = output;
+ }
+
+ public int doWrite(ByteChunk chunk, Response response)
+ throws IOException {
+ output.append(chunk);
+ return chunk.getLength();
+ }
+ }
+
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.coyote.servlet;
+
+
+import junit.framework.Test;
+
+public class LiteWatchdogJspTests extends LiteWatchdogServletTests {
+
+ public LiteWatchdogJspTests() {
+ super();
+ port = 8017;
+ testMatch =
+ //"precompileNegativeTest";
+ null;
+ // Test we know are failing - need to fix at some point.
+ exclude = new String[] {
+ "negativeDuplicateExtendsFatalTranslationErrorTest",
+ "negativeDuplicateErrorPageFatalTranslationErrorTest",
+ "negativeDuplicateInfoFatalTranslationErrorTest",
+ "negativeDuplicateLanguageFatalTranslationErrorTest",
+ "negativeDuplicateSessionFatalTranslationErrorTest",
+ "positiveIncludeCtxRelativeHtmlTest",
+ "precompileNegativeTest"
+ };
+ file = getWatchdogdir() + "/src/conf/jsp-gtest.xml";
+ goldenDir =
+ getWatchdogdir() + "/src/clients/org/apache/jcheck/jsp/client/";
+ targetMatch = "jsp-test";
+
+ }
+
+ public static Test suite() {
+ return new LiteWatchdogJspTests().getSuite(8017);
+ }
+
+}
+
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.coyote.servlet;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.tomcat.test.watchdog.WatchdogClient;
+
+
+public class LiteWatchdogServletTests extends WatchdogClient {
+
+
+ public LiteWatchdogServletTests() {
+ port = 8115;
+ goldenDir = getWatchdogdir() + "/src/clients/org/apache/jcheck/servlet/client/";
+ testMatch =
+ //"HttpServletResponseWrapperSetStatusMsgTest";
+ //"ServletContextAttributeAddedEventTest";
+ null;
+ // ex: "ServletToJSP";
+ file = getWatchdogdir() + "/src/conf/servlet-gtest.xml";
+ targetMatch = "gtestservlet-test";
+ }
+
+ protected void beforeSuite() {
+ // required for the tests
+ System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
+ "true");
+
+ try {
+ initServerWithWatchdog(getWatchdogdir());
+ } catch (ServletException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ int port = 8115;
+
+ protected void addConnector(TomcatLite liteServer) {
+ LiteTestHelper.addConnector(liteServer, port, true);
+ }
+
+ public void initServerWithWatchdog(String wdDir) throws ServletException,
+ IOException {
+
+ File f = new File(wdDir + "/build/webapps");
+
+ //CoyoteServer connector = new CoyoteServer();
+ //connector.addAdapter("/", new MapperAdapter());
+
+ TomcatLite liteServer = new TomcatLite();
+ addConnector(liteServer);
+ liteServer.init("webapps/ROOT", "/");
+
+ for (String s : new String[] {
+ "servlet-compat",
+ "servlet-tests",
+ "jsp-tests"} ) {
+ liteServer.init(f.getCanonicalPath() + "/" + s,
+ "/" + s);
+ }
+
+ //connector.init();
+ liteServer.init();
+ liteServer.start();
+
+ liteServer.startConnector();
+ }
+
+
+
+ protected void afterSuite(TestResult res) {
+ // no need to stop it - using daemon threads.
+ System.err.println("DONE");
+ }
+
+
+ /**
+ * Magic JUnit method
+ */
+ public static Test suite() {
+ // The individual targets are dups - and bad ones,
+ // RequestWrapper are missing part of the URL
+ return new LiteWatchdogServletTests().getSuite(8115);
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.coyote.servlet;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class TomcatLiteSimpleTest extends TestCase {
+
+ protected TomcatLite lite = new TomcatLite();
+
+ public void setUp() throws Exception {
+ LiteTestHelper.initServletsAndRun(lite, 8804);
+ }
+
+ public void tearDown() throws Exception {
+ lite.stop();
+ }
+
+ public void testSimpleRequest() throws Exception {
+ ByteChunk resb =
+ LiteTestHelper.getUrl("http://localhost:8804/test1/1stTest");
+ assertTrue(resb.getLength() > 0);
+ assertEquals("Hello world", resb.toString());
+ }
+
+
+}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.lite;
-
-import java.io.ByteArrayOutputStream;
-
-import org.apache.tomcat.util.res.StringManager;
-
-/**
- * Tables useful when converting byte arrays to and from strings of hexadecimal
- * digits.
- * Code from Ajp11, from Apache's JServ.
- *
- * @author Craig R. McClanahan
- */
-
-public final class HexDump {
-
-
- // -------------------------------------------------------------- Constants
- static final StringManager sm;
-
- /**
- * Table for HEX to DEC byte translation.
- */
- public static final int[] DEC = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- };
-
-
- /**
- * Table for DEC to HEX byte translation.
- */
- public static final byte[] HEX =
- { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
- (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
- (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
-
-
- // --------------------------------------------------------- Static Methods
-
-
- /**
- * Convert a String of hexadecimal digits into the corresponding
- * byte array by encoding each two hexadecimal digits as a byte.
- *
- * @param digits Hexadecimal digits representation
- *
- * @exception IllegalArgumentException if an invalid hexadecimal digit
- * is found, or the input string contains an odd number of hexadecimal
- * digits
- */
- public static byte[] convert(String digits) {
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- for (int i = 0; i < digits.length(); i += 2) {
- char c1 = digits.charAt(i);
- if ((i+1) >= digits.length())
- throw new IllegalArgumentException
- (sm.getString("hexUtil.odd"));
- char c2 = digits.charAt(i + 1);
- byte b = 0;
- if ((c1 >= '0') && (c1 <= '9'))
- b += ((c1 - '0') * 16);
- else if ((c1 >= 'a') && (c1 <= 'f'))
- b += ((c1 - 'a' + 10) * 16);
- else if ((c1 >= 'A') && (c1 <= 'F'))
- b += ((c1 - 'A' + 10) * 16);
- else
- throw new IllegalArgumentException
- (sm.getString("hexUtil.bad"));
- if ((c2 >= '0') && (c2 <= '9'))
- b += (c2 - '0');
- else if ((c2 >= 'a') && (c2 <= 'f'))
- b += (c2 - 'a' + 10);
- else if ((c2 >= 'A') && (c2 <= 'F'))
- b += (c2 - 'A' + 10);
- else
- throw new IllegalArgumentException
- (sm.getString("hexUtil.bad"));
- baos.write(b);
- }
- return (baos.toByteArray());
-
- }
-
-
- /**
- * Convert a byte array into a printable format containing a
- * String of hexadecimal digit characters (two per byte).
- *
- * @param bytes Byte array representation
- */
- public static String convert(byte bytes[]) {
-
- StringBuilder sb = new StringBuilder(bytes.length * 2);
- for (int i = 0; i < bytes.length; i++) {
- sb.append(convertDigit((bytes[i] >> 4)));
- sb.append(convertDigit((bytes[i] & 0x0f)));
- }
- return (sb.toString());
-
- }
-
-
- /**
- * Convert 4 hex digits to an int, and return the number of converted
- * bytes.
- *
- * @param hex Byte array containing exactly four hexadecimal digits
- *
- * @exception IllegalArgumentException if an invalid hexadecimal digit
- * is included
- */
- public static int convert2Int( byte[] hex ) {
- // Code from Ajp11, from Apache's JServ
-
- // assert b.length==4
- // assert valid data
- int len;
- if(hex.length < 4 ) return 0;
- if( DEC[hex[0]]<0 )
- throw new IllegalArgumentException(sm.getString("hexUtil.bad"));
- len = DEC[hex[0]];
- len = len << 4;
- if( DEC[hex[1]]<0 )
- throw new IllegalArgumentException(sm.getString("hexUtil.bad"));
- len += DEC[hex[1]];
- len = len << 4;
- if( DEC[hex[2]]<0 )
- throw new IllegalArgumentException(sm.getString("hexUtil.bad"));
- len += DEC[hex[2]];
- len = len << 4;
- if( DEC[hex[3]]<0 )
- throw new IllegalArgumentException(sm.getString("hexUtil.bad"));
- len += DEC[hex[3]];
- return len;
- }
-
-
-
- /**
- * Provide a mechanism for ensuring this class is loaded.
- */
- public static void load() {
- // Nothing to do
- }
-
- /**
- * [Private] Convert the specified value (0 .. 15) to the corresponding
- * hexadecimal digit.
- *
- * @param value Value to be converted
- */
- private static char convertDigit(int value) {
-
- value &= 0x0f;
- if (value >= 10)
- return ((char) (value - 10 + 'a'));
- else
- return ((char) (value + '0'));
-
- }
-
- /**
- * <code>getHexValue</code> displays a formatted hex
- * representation of the passed byte array. It also
- * allows for only a specified offset and length of
- * a particular array to be returned.
- *
- * @param bytes <code>byte[]</code> array to process.
- * @param pos offset to begin processing.
- * @param len number of bytes to process.
- * @return <code>String</code> formatted hex representation of processed
- * array.
- */
- public static String getHexDump(byte[] bytes, int pos, int len,
- boolean displayOffset) {
- StringBuilder out = new StringBuilder( len * 2 );
-
- for (int j = 0; j < len; j += 16) {
- hexLine(out, bytes, pos + j, pos + len, displayOffset);
- }
-
- return out.toString();
- }
-
- private static void hexLine(StringBuilder out,
- byte[] bytes, int start, int end,
- boolean displayOffset) {
-
- if ( displayOffset ) {
- out.append(convertDigit((int) (start >> 12)));
- out.append(convertDigit((int) (start >> 8)));
- out.append(convertDigit((int) (start >> 4)));
- out.append(convertDigit(start & 0x0F));
- out.append(": ");
- }
- for (int i = start; i < start + 16; i++) {
-
- if (i < end) {
- out.append(convertDigit((int) (bytes[i] >> 4)));
- out.append(convertDigit(bytes[i] & 0x0F));
- out.append(" ");
- } else {
- out.append(" ");
- }
- }
-
- out.append(" | ");
-
- for (int i = start; i < start + 16 && i < end; i++) {
- if( ! Character.isISOControl( (char)bytes[i] )) {
- out.append( new Character((char)bytes[i]) );
- } else {
- out.append( "." );
- }
- }
-
- out.append("\n");
- }
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.lite;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.coyote.OutputBuffer;
-import org.apache.coyote.Response;
-import org.apache.tomcat.lite.coyote.CoyoteConnector;
-import org.apache.tomcat.util.buf.ByteChunk;
-
-public class LiteTestHelper {
-
- public static void addContext(TomcatLite lite) throws ServletException {
- ServletContextImpl ctx =
- (ServletContextImpl) lite.addServletContext(null, null, "/test1");
-
- ctx.addServlet("test", new SimpleServlet());
- ctx.addMapping("/1stTest", "test");
-
- ctx.addServlet("testException", new HttpServlet() {
- public void doGet(HttpServletRequest req, HttpServletResponse res)
- throws IOException {
- throw new NullPointerException();
- }
- });
- ctx.addMapping("/testException", "testException");
- }
-
- public static void initServletsAndRun(TomcatLite lite, int port) throws ServletException, IOException {
- addContext(lite);
- lite.init();
- lite.start();
-
-
- if (port > 0) {
- // This should be added after all local initialization to avoid
- // the server from responding.
- // Alternatively, you can load this early but set it to return
- // 'unavailable' if load balancers depend on this.
- addConnector(lite, port, true);
-
- // At this point we can add contexts and inject requests, if we want to
- // do it over HTTP need to start the connector as well.
- lite.startConnector();
- }
- }
-
- public static void addConnector(TomcatLite lite,
- int port, boolean daemon) {
- CoyoteConnector coyoteAdapter = (CoyoteConnector) lite.getConnector();
- coyoteAdapter.setPort(port);
- coyoteAdapter.setDaemon(daemon);
- }
-
- /**
- * Get url using URLConnection.
- */
- public static ByteChunk getUrl(String path) throws IOException {
-
- ByteChunk out = new ByteChunk();
-
- URL url = new URL(path);
- URLConnection connection = url.openConnection();
- connection.setReadTimeout(5000);
- connection.connect();
- InputStream is = connection.getInputStream();
- BufferedInputStream bis = new BufferedInputStream(is);
- byte[] buf = new byte[2048];
- int rd = 0;
- while((rd = bis.read(buf)) > 0) {
- out.append(buf, 0, rd);
- }
- return out;
- }
-
- static class ByteChunkOutputBuffer implements OutputBuffer {
-
- protected ByteChunk output = null;
-
- public ByteChunkOutputBuffer(ByteChunk output) {
- this.output = output;
- }
-
- public int doWrite(ByteChunk chunk, Response response)
- throws IOException {
- output.append(chunk);
- return chunk.getLength();
- }
- }
-
-
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite;
-
-
-import junit.framework.Test;
-
-public class LiteWatchdogJspTests extends LiteWatchdogServletTests {
-
- public LiteWatchdogJspTests() {
- super();
- testMatch =
- //"precompileNegativeTest";
- null;
- // Test we know are failing - need to fix at some point.
- exclude = new String[] {
- "negativeDuplicateExtendsFatalTranslationErrorTest",
- "negativeDuplicateErrorPageFatalTranslationErrorTest",
- "negativeDuplicateInfoFatalTranslationErrorTest",
- "negativeDuplicateLanguageFatalTranslationErrorTest",
- "negativeDuplicateSessionFatalTranslationErrorTest",
- "positiveIncludeCtxRelativeHtmlTest",
- "precompileNegativeTest"
- };
- file = base + "/src/conf/jsp-gtest.xml";
- goldenDir =
- base + "/src/clients/org/apache/jcheck/jsp/client/";
- targetMatch = "jsp-test";
-
- }
-
- public static Test suite() {
- return new LiteWatchdogJspTests().getSuite();
- }
-
-}
-
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite;
-
-import java.io.File;
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-
-import junit.framework.Test;
-import junit.framework.TestResult;
-
-import org.apache.tomcat.test.watchdog.WatchdogClient;
-
-
-public class LiteWatchdogServletTests extends WatchdogClient {
-
-
- public LiteWatchdogServletTests() {
- goldenDir = base + "/src/clients/org/apache/jcheck/servlet/client/";
- testMatch =
- //"HttpServletResponseWrapperSetStatusMsgTest";
- //"ServletContextAttributeAddedEventTest";
- null;
- // ex: "ServletToJSP";
- file = base + "/src/conf/servlet-gtest.xml";
- targetMatch = "gtestservlet-test";
- }
-
- protected void beforeSuite() {
- // required for the tests
- System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
- "true");
- String path = System.getProperty("watchdog.home");
- if (path != null) {
- base = path;
- }
-
- try {
- initServerWithWatchdog(base);
- } catch (ServletException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- protected void addConnector(TomcatLite liteServer) {
- LiteTestHelper.addConnector(liteServer, 8080, true);
- }
-
- public void initServerWithWatchdog(String wdDir) throws ServletException,
- IOException {
-
- File f = new File(wdDir + "/build/webapps");
-
- //CoyoteServer connector = new CoyoteServer();
- //connector.addAdapter("/", new MapperAdapter());
-
- TomcatLite liteServer = new TomcatLite();
- addConnector(liteServer);
- liteServer.init("webapps/ROOT", "/");
-
- for (String s : new String[] {
- "servlet-compat",
- "servlet-tests",
- "jsp-tests"} ) {
- liteServer.init(f.getCanonicalPath() + "/" + s,
- "/" + s);
- }
-
- //connector.init();
- liteServer.init();
- liteServer.start();
-
- liteServer.startConnector();
- }
-
-
-
- protected void afterSuite(TestResult res) {
- // no need to stop it - using daemon threads.
- System.err.println("DONE");
- }
-
-
- /**
- * Magic JUnit method
- */
- public static Test suite() {
- // The individual targets are dups - and bad ones,
- // RequestWrapper are missing part of the URL
- return new LiteWatchdogServletTests().getSuite();
- }
-}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.tomcat.integration.simple.Main;
+import org.apache.tomcat.integration.simple.SimpleObjectManager;
+import org.apache.tomcat.lite.http.BaseMapper;
+import org.apache.tomcat.lite.http.DefaultHttpConnector;
+import org.apache.tomcat.lite.http.Dispatcher;
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnector;
+import org.apache.tomcat.lite.http.BaseMapper.ContextMapping;
+import org.apache.tomcat.lite.http.HttpConnector.HttpChannelEvents;
+import org.apache.tomcat.lite.http.services.EchoCallback;
+import org.apache.tomcat.lite.http.services.SleepCallback;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.SocketConnector;
+import org.apache.tomcat.lite.io.SslConnector;
+import org.apache.tomcat.lite.proxy.HttpProxyService;
+import org.apache.tomcat.lite.proxy.StaticContentService;
+import org.apache.tomcat.lite.service.IOStatus;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+/**
+ * Server with lost of test servlets.
+ *
+ * Used in tests - one is running for the entire suite.
+ *
+ * @author Costin Manolache
+ */
+public class TestMain {
+ static TestMain defaultServer;
+
+ SimpleObjectManager om;
+
+ static SocketConnector serverCon = new SocketConnector();
+
+ public static HttpConnector testClient = DefaultHttpConnector.get();
+ public static HttpConnector testServer = new HttpConnector(serverCon);
+ public static HttpConnector testProxy = new HttpConnector(serverCon);
+
+ static Dispatcher mcb;
+ static HttpProxyService proxy;
+
+
+ public static HttpConnector getTestServer() {
+ if (defaultServer == null) {
+ defaultServer = new TestMain();
+ defaultServer.run();
+ }
+ return defaultServer.testServer;
+ }
+
+
+ public static void initTestCallback(Dispatcher d) {
+ BaseMapper.ContextMapping mCtx = d.addContext(null, "", null, null, null, null);
+// testServer.setDebugHttp(true);
+// testServer.setDebug(true);
+
+ d.addWrapper(mCtx, "/", new StaticContentService()
+ .setContentType("text/html")
+ .setData("<a href='/proc/cpool/client'>Client pool</a><br/>" +
+ "<a href='/proc/cpool/server'>Server pool</a><br/>" +
+ "<a href='/proc/cpool/proxy'>Proxy pool</a><br/>" +
+ ""));
+
+ d.addWrapper(mCtx, "/hello", new StaticContentService().setData("Hello world"));
+ d.addWrapper(mCtx, "/2nd", new StaticContentService().setData("Hello world2"));
+ d.addWrapper(mCtx, "/echo/*", new EchoCallback());
+
+ d.addWrapper(mCtx, "/sleep/1", new SleepCallback().setData("sleep 1"));
+ d.addWrapper(mCtx, "/sleep/10", new SleepCallback().sleep(10000).setData(
+ "sleep 1"));
+
+ d.addWrapper(mCtx, "/chunked/*", new StaticContentService().setData("AAAA")
+ .chunked());
+
+ d.addWrapper(mCtx, "/proc/cpool/client", new IOStatus(testClient.cpool));
+ d.addWrapper(mCtx, "/proc/cpool/proxy", new IOStatus(testProxy.cpool));
+ d.addWrapper(mCtx, "/proc/cpool/server", new IOStatus(testServer.cpool));
+ }
+
+ static boolean RELEASE = true;
+ /**
+ * Blocking get, returns when the body has been read.
+ */
+ public static BBuffer get(String url) throws IOException {
+
+ BBuffer out = BBuffer.allocate();
+
+ HttpChannel aclient = DefaultHttpConnector.get().get(url);
+ aclient.sendRequest();
+ aclient.readAll(out,
+ //Long.MAX_VALUE);//
+ 2000000);
+ if (RELEASE) {
+ aclient.release(); // return connection to pool
+ }
+ return out;
+ }
+
+ public void run() {
+ String cfgFile = "org/apache/tomcat/lite/test.properties";
+ try {
+ startAll(cfgFile, 8000);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ protected void startAll(String cfgFile, int basePort) {
+ if (om == null) {
+ om = new SimpleObjectManager();
+ }
+
+ om.loadResource(cfgFile);
+
+ // // Override the port - don't want on 8080, Watchdog may run in same
+// // process
+// om.getProperties().put("org.apache.tomcat.lite.Connector.port",
+// Integer.toString(basePort + 800));
+
+ // From Main:
+ String run = (String) om.getProperty("RUN");
+ String[] runNames = run == null ? new String[] {} : run.split(",");
+
+ for (String name: runNames) {
+ Object main = om.get(name);
+
+ if (main instanceof Runnable) {
+ ((Runnable) main).run();
+ }
+ }
+
+ om.bind("HttpConnector-TestServer", testServer);
+ om.bind("HttpConnector", testClient);
+ om.bind("HttpConnector-Proxy", testProxy);
+
+ testServer.setOnCreate(new HttpChannelEvents() {
+ @Override
+ public void onCreate(HttpChannel data, HttpConnector extraData)
+ throws IOException {
+ //data.trace("BIND");
+ om.bind("AsyncHttp-" + data.getId(), data);
+ }
+ @Override
+ public void onDestroy(HttpChannel data, HttpConnector extraData)
+ throws IOException {
+ //data.trace("UNBIND");
+ om.unbind("AsyncHttp-" + data.getId());
+ }
+ });
+
+// ioConnector.setOnCreate(new IOConnector.ConnectedCallback() {
+// AtomicInteger ser = new AtomicInteger();
+// @Override
+// public void handleConnected(IOChannel data)
+// throws IOException {
+// data.setId("IOChannel-" + data.getTarget() + "-" +
+// ser.incrementAndGet());
+// om.bind(data.getId(), data);
+// }
+// });
+// ioConnector.setOnClose(new IOConnector.ClosedCallback() {
+// @Override
+// public void handleClosed(IOChannel data)
+// throws IOException {
+// System.err.println("UNBIND " + data.getId() + " " + data);
+// om.unbind(data.getId());
+// }
+// });
+// ioConnector.onNewWorker = new Callback<NioThread>() {
+// @Override
+// public void handle(NioThread data, Object extraData)
+// throws IOException {
+// om.bind((String) extraData, data);
+// }
+// };
+
+ int port = basePort + 903;
+ if (proxy == null) {
+ proxy = new HttpProxyService()
+ .withHttpClient(testClient);
+ testProxy.setPort(port);
+ testProxy.setDebugHttp(true);
+ testProxy.setDebug(true);
+
+ // dispatcher rejects 'http://'
+ testProxy.setHttpService(proxy);
+ try {
+ testProxy.start();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ port = basePort + 802;
+ initTestCallback(testServer.getDispatcher());
+ testServer.setPort(port);
+ try {
+ testServer.start();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ port = basePort + 443;
+
+ }
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ System.err.println("Done");
+ }
+ public void start() {
+ System.err.println("Done1");
+ }
+ });
+
+
+// try {
+// ServletContextImpl ctx = (ServletContextImpl) tomcat.addServletContext(null, null, "/jmx");
+// // tomcat is already started, need to call init explicitely
+// ((ServletContextImpl) ctx).loadConfig();
+//
+// Servlet servlet = new JMXProxyServlet();
+// ServletRegistration.Dynamic jmxServlet = ctx.addServlet("jmx",
+// servlet);
+// jmxServlet.addMapping("/jmx");
+// // TODO: init servlet
+// servlet.init(new ServletConfigImpl(ctx, null, null));
+//
+// ctx.start();
+//
+// } catch (ServletException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+
+ }
+
+ static {
+ SslConnector.fixUrlConnection();
+ }
+
+ public static ByteChunk getUrl(String path) throws IOException {
+ ByteChunk out = new ByteChunk();
+ getUrl(path, out, null);
+ return out;
+ }
+
+ public static int getUrl(String path,
+ ByteChunk out,
+ Map<String, List<String>> resHead) throws IOException {
+ URL url = new URL(path);
+ HttpURLConnection connection =
+ (HttpURLConnection) url.openConnection();
+ // connection.setReadTimeout(100000);
+ connection.connect();
+ int rc = connection.getResponseCode();
+ if (resHead != null) {
+ Map<String, List<String>> head = connection.getHeaderFields();
+ resHead.putAll(head);
+ }
+ InputStream is = connection.getInputStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ byte[] buf = new byte[2048];
+ int rd = 0;
+ while((rd = bis.read(buf)) > 0) {
+ out.append(buf, 0, rd);
+ }
+ return rc;
+ }
+
+
+ public static void main(String[] args) throws Exception, IOException {
+ TestMain testMain = new TestMain();
+ TestMain.defaultServer = testMain;
+ testMain.om = new SimpleObjectManager(args);
+ testMain.run();
+ Main.waitStop();
+ }
+
+
+}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tomcat.lite;
-
-import junit.framework.TestCase;
-
-import org.apache.tomcat.util.buf.ByteChunk;
-
-public class TomcatLiteSimpleTest extends TestCase {
-
- protected TomcatLite lite = new TomcatLite();
-
- public void setUp() throws Exception {
- LiteTestHelper.initServletsAndRun(lite, 8804);
- }
-
- public void tearDown() throws Exception {
- lite.stop();
- }
-
- public void testSimpleRequest() throws Exception {
- ByteChunk resb =
- LiteTestHelper.getUrl("http://localhost:8804/test1/1stTest");
- assertTrue(resb.length() > 0);
- assertEquals("Hello world", resb.toString());
- }
-
-
-}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.http;
+
+import org.apache.tomcat.lite.io.CBuffer;
+
+import junit.framework.TestCase;
+
+public class DispatcherTest extends TestCase {
+
+ public void testMapper() throws Exception {
+ BaseMapper mapper = new BaseMapper();
+
+ String[] welcomes = new String[2];
+ welcomes[0] = "index.html";
+ welcomes[1] = "foo.html";
+
+ mapper.addContext("test1.com", "", "context0", new String[0], null, null);
+ mapper.addContext("test1.com", "/foo", "context1", new String[0], null, null);
+ mapper.addContext("test1.com", "/foo/bar", "context2", welcomes, null, null);
+ mapper.addContext("test1.com", "/foo/bar/bla", "context3", new String[0], null, null);
+
+ mapper.addWrapper("test1.com", "/foo/bar", "/fo/*", "wrapper0");
+ mapper.addWrapper("test1.com", "/foo/bar", "/", "wrapper1");
+ mapper.addWrapper("test1.com", "/foo/bar", "/blh", "wrapper2");
+ mapper.addWrapper("test1.com", "/foo/bar", "*.jsp", "wrapper3");
+ mapper.addWrapper("test1.com", "/foo/bar", "/blah/bou/*", "wrapper4");
+ mapper.addWrapper("test1.com", "/foo/bar", "/blah/bobou/*", "wrapper5");
+ mapper.addWrapper("test1.com", "/foo/bar", "*.htm", "wrapper6");
+
+ mapper.addContext("asdf.com", "", "context0", new String[0], null, null);
+
+ MappingData mappingData = new MappingData();
+
+ CBuffer host = CBuffer.newInstance();
+ host.set("test1.com");
+
+ CBuffer uri = CBuffer.newInstance();
+ uri.set("/foo/bar/blah/bobou/foo");
+
+ mapper.map(host, uri, mappingData);
+
+ assertEquals("context2", mappingData.context.toString());
+ assertEquals("/foo/bar", mappingData.contextPath.toString());
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.http.HttpChannel.HttpService;
+import org.apache.tomcat.lite.http.HttpChannel.RequestCompleted;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.CBuffer;
+import org.apache.tomcat.lite.io.IOBuffer;
+import org.apache.tomcat.lite.io.IOChannel;
+import org.apache.tomcat.lite.io.IOConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector.MemoryIOChannel;
+
+public class HttpChannelInMemoryTest extends TestCase {
+
+ MemoryIOConnector memoryServerConnector = new MemoryIOConnector();
+ MemoryIOConnector memoryClientConnector =
+ new MemoryIOConnector().withServer(memoryServerConnector);
+
+
+ // Used for pipelined requests - after the first request is
+ // processed, a new HttpChannel is used ( first may still be
+ // in use )
+ HttpChannel lastServer;
+
+ // The server channel will use this for I/O...
+ MemoryIOConnector.MemoryIOChannel net = new MemoryIOChannel();
+
+ HttpConnector serverConnector = new HttpConnector(memoryServerConnector) {
+ @Override
+ public HttpChannel get(CharSequence target) throws IOException {
+ throw new IOException();
+ }
+ public HttpChannel getServer() {
+ lastServer = new HttpChannel().serverMode(true);
+ lastServer.withBuffers(net);
+ lastServer.setConnector(this);
+ //lastServer.withIOConnector(memoryServerConnector);
+ return lastServer;
+ }
+ };
+
+ HttpConnector httpClient = new HttpConnector(memoryClientConnector);
+
+ boolean hasBody = false;
+ boolean bodyDone = false;
+ boolean bodySentDone = false;
+ boolean headersDone = false;
+ boolean allDone = false;
+
+
+ HttpChannel http = serverConnector.getServer();
+
+ public void setUp() throws IOException {
+ serverConnector.setHttpService(null);
+ }
+
+
+ public void test2Req() throws IOException {
+ String req = "GET /index.html?q=b&c=d HTTP/1.1\r\n" +
+ "Host: Foo.com \n" +
+ "H2:Bar\r\n" +
+ "H3: Foo \r\n" +
+ " Bar\r\n" +
+ "H4: Foo\n" +
+ " Bar\n" +
+ "\r\n" +
+ "HEAD /r2? HTTP/1.1\n" +
+ "Host: Foo.com\r\n" +
+ "H3: Foo \r\n" +
+ " Bar\r\n" +
+ "H4: Foo\n" +
+ " Bar\n" +
+ "\r\n";
+ net.getIn().append(req);
+
+ assertTrue(http.getRequest().method().equals("GET"));
+ assertTrue(http.getRequest().protocol().equals("HTTP/1.1"));
+ assertEquals(http.getRequest().getMimeHeaders().size(), 4);
+ assertEquals(http.getRequest().getMimeHeaders().getHeader("Host").toString(),
+ "Foo.com");
+ assertEquals(http.getRequest().getMimeHeaders().getHeader("H2").toString(),
+ "Bar");
+
+ http.getOut().append("Response1");
+ http.getOut().close();
+ http.startSending();
+ http.release();
+
+ // now second response must be in.
+ // the connector will create a new http channel
+
+ http = lastServer;
+
+ assertTrue(http.getRequest().method().equals("HEAD"));
+ assertTrue(http.getRequest().protocol().equals("HTTP/1.1"));
+ assertTrue(http.getRequest().getMimeHeaders().size() == 3);
+ assertTrue(http.getRequest().getMimeHeaders().getHeader("Host")
+ .equals("Foo.com"));
+ }
+
+ public void testMultiLineHead() throws IOException {
+ http.getNet().getIn().append("GET / HTTP/1.0\n" +
+ "Cookie: 1234\n" +
+ " 456 \n" +
+ "Connection: Close\n\n");
+ http.getNet().getIn().close();
+
+ MultiMap headers = http.getRequest().getMimeHeaders();
+ CBuffer cookie = headers.getHeader("Cookie");
+ CBuffer conn = headers.getHeader("Connection");
+ assertEquals(conn.toString(), "Close");
+ assertEquals(cookie.toString(), "1234 456");
+
+ assertEquals(http.headRecvBuf.toString(),
+ "GET / HTTP/1.0\n" +
+ "Cookie: 1234 456 \n" + // \n -> trailing space
+ "Connection: Close\n\n");
+ }
+
+ public void testCloseSocket() throws IOException {
+ http.getNet().getIn().append("GET / HTTP/1.1\n"
+ + "Host: localhost\n"
+ + "\n");
+ assertTrue(http.keepAlive());
+
+ http.getNet().getIn().close();
+ assertFalse(http.keepAlive());
+ }
+
+ public void test2ReqByte2Byte() throws IOException {
+ String req = "GET /index.html?q=b&c=d HTTP/1.1\r\n" +
+ "Host: Foo.com \n" +
+ "H2:Bar\r\n" +
+ "H3: Foo \r\n" +
+ " Bar\r\n" +
+ "H4: Foo\n" +
+ " Bar\n" +
+ "\r\n" +
+ "HEAD /r2? HTTP/1.1\n" +
+ "Host: Foo1.com\n" +
+ "H3: Foo \r\n" +
+ " Bar\r\n" +
+ "\r\n";
+ for (int i = 0; i < req.length(); i++) {
+ net.getIn().append(req.charAt(i));
+ }
+
+ assertTrue(http.getRequest().method().equals("GET"));
+ assertTrue(http.getRequest().protocol().equals("HTTP/1.1"));
+ assertTrue(http.getRequest().getMimeHeaders().size() == 4);
+ assertTrue(http.getRequest().getMimeHeaders().getHeader("Host")
+ .equals("Foo.com"));
+
+ // send a response
+ http.sendBody.append("Response1");
+ http.getOut().close();
+
+ http.startSending(); // This will trigger a pipelined request
+
+ http.release(); // now second response must be in
+
+ http = lastServer;
+ assertTrue(http.getRequest().method().equals("HEAD"));
+ assertTrue(http.getRequest().protocol().equals("HTTP/1.1"));
+ assertTrue(http.getRequest().getMimeHeaders().size() == 2);
+ assertTrue(http.getRequest().getMimeHeaders().getHeader("Host")
+ .equals("Foo1.com"));
+
+ // send a response - service method will be called
+ http.sendBody.append("Response2");
+ http.getOut().close();
+ http.release(); // now second response must be in
+
+
+ }
+
+ public void testEndWithoutFlushCallbacks() throws IOException {
+ http.setCompletedCallback(new RequestCompleted() {
+ public void handle(HttpChannel data, Object extra)
+ throws IOException {
+ allDone = true;
+ }
+ });
+ http.getNet().getIn().append(POST);
+ http.getNet().getIn().close();
+
+ http.sendBody.queue("Hi");
+ http.getOut().close();
+ http.startSending(); // will call handleEndSend
+
+ assertTrue(allDone);
+
+ }
+
+ public void testCallbacks() throws IOException {
+ http.setCompletedCallback(new RequestCompleted() {
+ public void handle(HttpChannel data, Object extra)
+ throws IOException {
+ allDone = true;
+ }
+ });
+ http.setHttpService(new HttpService() {
+ public void service(HttpRequest httpReq, HttpResponse httpRes)
+ throws IOException {
+ headersDone = true;
+ }
+ });
+ http.setDataReceivedCallback(new IOConnector.DataReceivedCallback() {
+ @Override
+ public void handleReceived(IOChannel ch) throws IOException {
+ if (ch.getIn().isAppendClosed()) {
+ bodyDone = true;
+ }
+ }
+ });
+ http.setDataFlushedCallback(new IOConnector.DataFlushedCallback() {
+ @Override
+ public void handleFlushed(IOChannel ch) throws IOException {
+ if (ch.getOut().isAppendClosed()) {
+ bodySentDone = true;
+ }
+ }
+ });
+
+ // Inject the request
+ http.getNet().getIn().append(POST);
+ assertTrue(headersDone);
+ http.getNet().getIn().append("1234");
+
+ http.getNet().getIn().close();
+ assertTrue(bodyDone);
+
+
+ http.sendBody.queue("Hi");
+ http.getOut().close();
+ http.startSending();
+ assertTrue(bodySentDone);
+
+ assertTrue(allDone);
+
+ }
+
+ public static String POST = "POST / HTTP/1.0\n" +
+ "Connection: Close\n" +
+ "Content-Length: 4\n\n" +
+ "1234";
+
+ public void testClose() throws IOException {
+ http.getNet().getIn().append(POST);
+ http.getNet().getIn().close();
+
+ HttpBody receiveBody = http.receiveBody;
+ IOBuffer appData = receiveBody;
+ BBuffer res = BBuffer.allocate(1000);
+ appData.readAll(res);
+
+ assertEquals(res.toString(), "1234");
+ assertFalse(http.keepAlive());
+ assertFalse(http.keepAlive());
+
+ http.sendBody.queue(res);
+ http.getOut().close();
+ http.startSending();
+
+ assertTrue(net.getOut().isAppendClosed());
+ assertTrue(net.out.toString().indexOf("\n1234") > 0);
+
+ }
+
+ public void testReadLine() throws Exception {
+ http.getNet().getIn().append("POST / HTTP/1.0\n" +
+ "Content-Length: 28\n\n" +
+ "Line 1\n" +
+ "Line 2\r\n" +
+ "Line 3\r" +
+ "Line 4");
+ http.getNet().getIn().close();
+
+ BufferedReader r = http.getRequest().getReader();
+ assertEquals("Line 1", r.readLine());
+ assertEquals("Line 2", r.readLine());
+ assertEquals("Line 3", r.readLine());
+ assertEquals("Line 4", r.readLine());
+ assertEquals(null, r.readLine());
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.http;
+
+import java.io.IOException;
+
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.CBuffer;
+
+import junit.framework.TestCase;
+
+public class HttpChannelTest extends TestCase {
+
+ HttpChannel ch = new HttpChannel().serverMode(true);
+ HttpRequest req = ch.getRequest();
+
+
+ BBuffer head = BBuffer.allocate();
+ BBuffer line = BBuffer.wrapper();
+ BBuffer name = BBuffer.wrapper();
+ BBuffer value = BBuffer.wrapper();
+
+ BBuffer statusB = BBuffer.wrapper();
+ BBuffer msgB = BBuffer.wrapper();
+ BBuffer methodB = BBuffer.wrapper();
+ BBuffer queryB = BBuffer.wrapper("");
+ BBuffer requestB = BBuffer.wrapper();
+ BBuffer protoB = BBuffer.wrapper();
+
+ BBuffer l7 = BBuffer.wrapper("GET \n");
+ BBuffer l8 = BBuffer.wrapper("GET /\n");
+ BBuffer l9 = BBuffer.wrapper("GET /a?b\n");
+ BBuffer l10 = BBuffer.wrapper("GET /a?b HTTP/1.0\n");
+ BBuffer l11 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b");
+ BBuffer l12 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\n");
+
+ BBuffer f1 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\n\n");
+ BBuffer f2 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\n\r\n");
+ BBuffer f3 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\r");
+ BBuffer f4 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\n\r");
+
+
+ public void reqTest(String lineS, String method, String req,
+ String qry, String proto) throws IOException {
+ BBuffer line = BBuffer.wrapper(lineS);
+ queryB.recycle();
+ protoB.recycle();
+ requestB.recycle();
+ methodB.recycle();
+ ch.parseRequestLine(line, methodB, requestB, queryB, protoB);
+ assertEquals(proto, protoB.toString());
+ assertEquals(req, requestB.toString());
+ assertEquals(qry, queryB.toString());
+ assertEquals(method, methodB.toString());
+ }
+
+ public void testParams() throws IOException {
+ MultiMap params = processQry("a=b&c=d");
+ assertEquals("b", params.getString("a"));
+ }
+
+ private MultiMap processQry(String qry) throws IOException {
+ BBuffer head = BBuffer.wrapper("GET /a?" + qry + " HTTP/1.0\n" +
+ "Host: a\n\n");
+ ch.parseMessage(head);
+ MultiMap params = req.getParameters();
+ return params;
+ }
+
+ public void testParseReq() throws IOException {
+ reqTest("GET / HTTP/1.0", "GET", "/", "", "HTTP/1.0");
+ reqTest("GET", "GET", "", "", "");
+ reqTest("GET / HTTP/1.0", "GET", "/", "", "HTTP/1.0");
+ reqTest("GET / HTTP/1.0", "GET", "/", "", "HTTP/1.0");
+ reqTest("GET /?b HTTP/1.0", "GET", "/", "b", "HTTP/1.0");
+ reqTest("GET ?a HTTP/1.0", "GET", "", "a", "HTTP/1.0");
+ reqTest("GET a HTTP/1.0", "GET", "a", "", "HTTP/1.0");
+ reqTest("GET a? HTTP/1.0", "GET", "a", "", "HTTP/1.0");
+ }
+
+ public void headTest(String headS, String expName, String expValue,
+ String expLine, String expRest) throws IOException {
+ head = BBuffer.wrapper(headS);
+ head.readLine(line);
+ ch.parseHeader(head, line, name, value);
+
+ assertEquals(expName, name.toString());
+ assertEquals(expValue, value.toString());
+
+ assertEquals(expLine, line.toString());
+ assertEquals(expRest, head.toString());
+ }
+
+ public void testParseHeader() throws IOException {
+ headTest("a:b\n", "a", "b", "", "");
+ headTest("a :b\n", "a", "b", "", "");
+ headTest("a : b\n", "a", "b", "", "");
+ headTest("a : b\n", "a", "b", "", "");
+ headTest("a : b c \n", "a", "b c", "", "");
+ headTest("a : b c\n", "a", "b c", "", "");
+ headTest("a : b c\n", "a", "b c", "", "");
+ headTest("a : b \n c\n", "a", "b c", "", "");
+ headTest("a : b \n c\n", "a", "b c", "", "");
+ headTest("a : b \n c\nd:", "a", "b c", "", "d:");
+
+ }
+
+ public void responseTest(String lineS, String proto, String status,
+ String msg) throws IOException {
+ protoB.recycle();
+ statusB.recycle();
+ msgB.recycle();
+ BBuffer line = BBuffer.wrapper(lineS);
+ ch.parseResponseLine(line,
+ protoB, statusB, msgB);
+ assertEquals(proto, protoB.toString());
+ assertEquals(status, statusB.toString());
+ assertEquals(msg, msgB.toString());
+ }
+
+ public void testResponse() throws Exception {
+ responseTest("HTTP/1.1 200 OK", "HTTP/1.1", "200", "OK");
+ responseTest("HTTP/1.1 200 OK", "HTTP/1.1", "200", "OK");
+ responseTest("HTTP/1.1 200", "HTTP/1.1", "200", "");
+ responseTest("HTTP/1.1", "HTTP/1.1", "", "");
+ }
+
+
+
+}
--- /dev/null
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.lite.http;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.tomcat.lite.TestMain;
+import org.apache.tomcat.lite.http.HttpChannel.HttpService;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.SslConnector;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class HttpsTest extends TestCase {
+
+ static int port = 8443;
+ HttpConnector con;
+ HttpConnector httpClient;
+
+ public void setUp() {
+ Logger.getLogger("SSL").setLevel(Level.FINEST);
+ }
+
+ public void tearDown() {
+ if (con != null) {
+ con.stop();
+ }
+ if (httpClient != null) {
+ httpClient.stop();
+ }
+ }
+
+ static HttpConnector initServer(int port) throws IOException {
+ SslConnector sslCon = new SslConnector()
+ .setKeysResource("org/apache/tomcat/lite/http/test.keystore", "changeit");
+
+ HttpConnector con = new HttpConnector(sslCon);
+ con.setPort(port);
+
+ addService(con);
+ return con;
+ }
+
+ private static void addService(HttpConnector con) throws IOException {
+ con.setMaxHttpPoolSize(0);
+// con.setDebug(true);
+// con.setDebugHttp(true);
+
+ con.getDispatcher().setDefaultService(new HttpService() {
+ @Override
+ public void service(HttpRequest httpReq, HttpResponse httpRes)
+ throws IOException {
+ httpRes.setHeader("Connection", "close");
+ httpRes.getBodyWriter().write("Hello");
+ }
+ });
+ con.start();
+ }
+
+ public void testSimpleClient() throws Exception {
+ SslConnector sslCon = new SslConnector();
+ httpClient = new HttpConnector(sslCon);
+// httpClient.setDebug(true);
+// httpClient.setDebugHttp(true);
+ httpClient.setMaxHttpPoolSize(0);
+ con = initServer(++port);
+ checkResponse(httpClient);
+ }
+
+
+ public void testSimpleServer() throws Exception {
+ con = initServer(++port);
+ ByteChunk res = TestMain.getUrl("https://localhost:" + port +
+ "/examples/servlets/servlet/HelloWorldExample");
+ assertTrue(res.toString().indexOf("Hello") >= 0);
+ }
+
+
+ private void checkResponse(HttpConnector httpClient) throws Exception {
+ HttpChannel ch = httpClient.get("localhost", port);
+ ch.getRequest().setRequestURI("/hello");
+ ch.getRequest().setProtocol("HTTP/1.0");
+ // problems with keep alive !!!
+ ch.sendRequest();
+ BBuffer res = ch.readAll(null, 1000000);
+
+ assertTrue(res.toString().indexOf("Hello") >= 0);
+ }
+
+ public void testSimpleClient20() throws Exception {
+ SslConnector sslCon = new SslConnector();
+ httpClient = new HttpConnector(sslCon);
+// httpClient.setDebug(true);
+// httpClient.setDebugHttp(true);
+
+ con = initServer(++port);
+ for (int i = 0; i < 20; i++) {
+ checkResponse(httpClient);
+ }
+ }
+
+ public void testSimpleRequestGoogle() throws Exception {
+ SslConnector sslCon = new SslConnector();
+ httpClient = new HttpConnector(sslCon);
+ HttpChannel client = httpClient.get("www.google.com", 443);
+ client.getRequest().setRequestURI("/accounts/ServiceLogin");
+ client.sendRequest();
+
+ BBuffer res = BBuffer.allocate(10000);
+ client.readAll(res, 1000000);
+ assertTrue(res.toString().indexOf("<title>Google Accounts</title>") > 0);
+ }
+
+
+ /**
+ * Use byte[] for cert - avoids using the store file.
+ * This may be nice for:
+ * - tests without a file
+ * - frameworks managing configs - no need to deal with files
+ * @throws Exception
+ *
+ */
+ public void testSeverWithKeys() throws Exception {
+ Base64 b64 = new Base64();
+
+
+ byte[] keyBytes = b64.decode(PRIVATE_KEY);
+
+ SslConnector sslCon = new SslConnector()
+ .setKeys(CERTIFICATE, keyBytes);
+
+ HttpConnector con = new HttpConnector(sslCon);
+ con.setPort(++port);
+ addService(con);
+
+ ByteChunk res = TestMain.getUrl("https://localhost:" + port +
+ "/examples/servlets/servlet/HelloWorldExample");
+ assertTrue(res.toString().indexOf("Hello") >= 0);
+
+ }
+
+
+ //byte[] encoded =
+ // SslConnector.getCertificateFromStore(
+ // "test/org/apache/tomcat/lite/http/test.keystore",
+ // "changeit");
+ //byte[] encoded =
+ // SslConnector.getPrivateKeyFromStore(
+ // "test/org/apache/tomcat/lite/http/test.keystore",
+ // "changeit");
+ //
+ //byte[] b64b = b64.encode(encoded);
+ //System.out.println(new String(b64b));
+ static String PRIVATE_KEY =
+ "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALGOFqjC4Fefz0oOcfJeS8eLV8jY" +
+ "zA3sHUnTKmASfgfhG8prWUgSEq7O/849MrBysiKpIvTN8R+ykV4QCAxauGURDsNI2ZtAv23YX2Mb" +
+ "cfYfYqD0tgHEn355HKey0ICgmRuq3norlUWAH3hRv5qiQMc0UIhNrmdTs0jyvQ8E8AlZAgMBAAEC" +
+ "gYBybr8P2Tk5gBfbBOBPcpKocpgLLB6nQmvF7sC61nA/p8d/eBw8pNlBrMuVIkAPFHzWdee/mxMy" +
+ "eKXT18U4ISgBdIKLF9LwILhIgR8CwElLucmF2OdXqFe7baBIFI6OaqLvDgOwdHSIS6uZhAWOWIAZ" +
+ "38DhJbHMzPpfeBv1bAIhAQJBAPwhjzWqSWZjAfcED4htKa/ZSbdqMa1iYtveoHdXIcLuj4Ck1DKQ" +
+ "EFpzLnUe2gwul/TDcoW3ZVp85jn7jwnrNDECQQC0R5LgkGdGNMBih4kPU87tHFHUnggSMyIOBnCE" +
+ "XuQEN6i68VOwbdm2F7Rg1XGHD8IIJmVeiTSgLtS/mJRht6WpAkEAqs9VhQbTaTDkEOPIXiWOW1q6" +
+ "rS6dbxg7XzdowNDfx3706zM/qu2clpp3u9Ll5+DdA24xtNM1L+Nz2Y5KLm8Q0QJAQqpxEx/zQNAD" +
+ "EKyEL6nTTHV7gT+LRoeoIT2aYCji8vhOKgtR4l1M8/xiFKj5mXNnUjI4rDPaxR1sSQm4XUZXOQJB" +
+ "AJaCD0AhacU+KaOtk65tBJ7N2dKTbc5gs/CAz1uGgJtoD/jPjELMQwrxdp6AZP6+L6osqy6zDI3W" +
+ "zNHXS+wWAd0=";
+
+ static String CERTIFICATE =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICUzCCAbygAwIBAgIESviASzANBgkqhkiG9w0BAQUFADBuMRAwDgYDVQQGEwdVbmtub3duMRAw" +
+ "DgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYD" +
+ "VQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMDkxMTA5MjA0OTE1WhcNMTAwMjA3" +
+ "MjA0OTE1WjBuMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdV" +
+ "bmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2Nh" +
+ "bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGOFqjC4Fefz0oOcfJeS8eLV8jYzA3s" +
+ "HUnTKmASfgfhG8prWUgSEq7O/849MrBysiKpIvTN8R+ykV4QCAxauGURDsNI2ZtAv23YX2MbcfYf" +
+ "YqD0tgHEn355HKey0ICgmRuq3norlUWAH3hRv5qiQMc0UIhNrmdTs0jyvQ8E8AlZAgMBAAEwDQYJ" +
+ "KoZIhvcNAQEFBQADgYEAPHUr1BDENlV28yIQvJOWKYbcNWLd6Cp8xCltSI897xhPpKQ5tDvs+l0g" +
+ "VfdBv5+jou0F5gbCkqgclBuUnUUWsU7r4HYBLVB8FiGSy9v5yuFJWyMMLJkWAfBgzxV1nHsCPhOn" +
+ "rspSB+i6bwag0i3ENXstD/Fg1lN/7l9dRpurneI=\n" +
+ "-----END CERTIFICATE-----\n\n";
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.http;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.TestMain;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.CBuffer;
+import org.apache.tomcat.lite.io.SocketConnector;
+
+public class LiveHttp1Test extends TestCase {
+ // Proxy tests extend this class, run same tests via proxy on 8903
+ protected int clientPort = 8802;
+
+ HttpChannel httpClient;
+
+ BBuffer bodyRecvBuffer = BBuffer.allocate(1024);
+
+ int to = 1000;
+
+ public void setUp() throws IOException {
+ // DefaultHttpConnector.get().setDebug(true);
+ // DefaultHttpConnector.get().setDebugHttp(true);
+ TestMain.getTestServer();
+
+ httpClient = DefaultHttpConnector.get().get("localhost", clientPort);
+
+ bodyRecvBuffer.recycle();
+ }
+
+ public void tearDown() throws Exception {
+ if (httpClient != null) {
+ httpClient.release(); // async
+ httpClient = null;
+ }
+ }
+
+ public void testSimpleRequest() throws Exception {
+ httpClient.getRequest().requestURI().set("/hello");
+
+ httpClient.sendRequest();
+ httpClient.readAll(bodyRecvBuffer, to);
+ assertEquals("Hello world", bodyRecvBuffer.toString());
+ }
+
+ public void testPoolGetRelease() throws Exception {
+ HttpConnector con = new HttpConnector(new SocketConnector());
+ con.setMaxHttpPoolSize(10);
+ HttpChannel httpCh = con.get("localhost", clientPort);
+ httpCh.release();
+
+ httpCh = con.get("localhost", clientPort);
+ httpCh.release();
+
+ httpCh = con.get("localhost", clientPort);
+ httpCh.release();
+
+ }
+
+ public void testSimpleChunkedRequest() throws Exception {
+ httpClient.getRequest().requestURI().set("/chunked/foo");
+ httpClient.sendRequest();
+ httpClient.readAll(bodyRecvBuffer, to);
+ assertTrue(bodyRecvBuffer.toString().indexOf("AAA") >= 0);
+ }
+
+ // Check waitResponseHead()
+ public void testRequestHead() throws Exception {
+ httpClient.getRequest().requestURI().set("/echo/foo");
+
+ // Send the request, wait response
+ httpClient.sendRequest();
+
+ httpClient.readAll(bodyRecvBuffer, to);
+ assertTrue(bodyRecvBuffer.toString().indexOf("GET /echo/foo") > 0);
+ }
+
+ public void test10() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ testSimpleRequest();
+ tearDown();
+ setUp();
+
+ notFound();
+ tearDown();
+ setUp();
+
+ testSimpleRequest();
+ tearDown();
+ setUp();
+ }
+ }
+
+ public void notFound() throws Exception {
+ httpClient.getRequest().requestURI().set("/foo");
+ httpClient.sendRequest();
+ httpClient.readAll(bodyRecvBuffer, to);
+ }
+
+ // compression not implemented
+ public void testGzipRequest() throws Exception {
+ httpClient.getRequest().requestURI().set("/hello");
+ httpClient.getRequest().setHeader("accept-encoding",
+ "gzip");
+
+ // Send the request, wait response
+ httpClient.sendRequest();
+ // cstate.waitResponseHead(10000); // headers are received
+ // ByteChunk data = new ByteChunk(1024);
+ // acstate.serializeResponse(acstate.res, data);
+
+ // System.err.println(bodyRecvBuffer.toString());
+
+ httpClient.readAll(bodyRecvBuffer, to);
+ // Done
+ }
+
+ public void testWrongPort() throws Exception {
+ httpClient = DefaultHttpConnector.get().get("localhost", 18904);
+ httpClient.getRequest().requestURI().set("/hello");
+
+ httpClient.sendRequest();
+
+ try {
+ httpClient.readAll(bodyRecvBuffer, to);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ return;
+ }
+ fail("Error");
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.http;
+
+import org.apache.tomcat.lite.http.MultiMap.Entry;
+
+import junit.framework.TestCase;
+
+public class MultiMapTest extends TestCase {
+
+ MultiMap map = new MultiMap();
+ MultiMap lmap = new MultiMap().insensitive();
+
+ public void testAdd() {
+ map.add("foo", "bar");
+ assertEquals("bar", map.get("foo").toString());
+ }
+
+ public void testRemove() {
+ map.add("foo", "bar");
+ map.add("foo", "bar");
+ map.add("foo1", "bar");
+ assertEquals(3, map.count);
+ map.remove("foo");
+ assertEquals(1, map.count);
+ }
+
+ public void testRemove1() {
+ map.add("foo", "bar");
+ map.add("foo1", "bar");
+ map.add("foo", "bar");
+ assertEquals(3, map.count);
+ map.remove("foo");
+ assertEquals(1, map.count);
+ map.remove("foo1");
+ assertEquals(0, map.count);
+ }
+
+ public void testCase() {
+ lmap.add("foo", "bar1");
+ lmap.add("Foo", "bar2");
+ lmap.add("a", "bar3");
+ lmap.add("B", "bar4");
+ assertEquals(4, lmap.count);
+ assertEquals(3, lmap.map.size());
+
+ assertEquals("bar3", lmap.getString("a"));
+ assertEquals("bar3", lmap.getString("A"));
+ assertEquals("bar1", lmap.getString("Foo"));
+ Entry entry = lmap.getEntry("FOO");
+ assertEquals(2, entry.values.size());
+ }
+
+}
--- /dev/null
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.http.services;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpRequest;
+import org.apache.tomcat.lite.http.HttpResponse;
+import org.apache.tomcat.lite.http.HttpChannel.HttpService;
+import org.apache.tomcat.lite.io.IOBuffer;
+
+/**
+ * Response is plain/text, copy of the received request
+ */
+public class EchoCallback implements HttpService {
+ Logger log = Logger.getLogger("coyote.static");
+
+ String contentType = "text/plain";
+
+
+ public EchoCallback() {
+ }
+
+ @Override
+ public void service(HttpRequest req, HttpResponse res) throws IOException {
+ HttpChannel sproc = req.getHttpChannel();
+ res.setStatus(200);
+ res.setContentType(contentType);
+
+ IOBuffer tmp = new IOBuffer(null);
+ req.serialize(tmp);
+
+ sproc.getOut().append("REQ HEAD:\n");
+ sproc.getOut().append(tmp.readAll(null));
+ IOBuffer reqBuf = sproc.getOut();
+
+ reqBuf.append("\nCONTENT_LENGTH:")
+ .append(Long.toString(req.getContentLength()))
+ .append("\n");
+//
+// sproc.release();
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.http.services;
+
+import java.io.IOException;
+
+import org.apache.tomcat.lite.http.HttpRequest;
+import org.apache.tomcat.lite.http.HttpResponse;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.proxy.StaticContentService;
+
+/**
+ * Test adapters that sleeps, for load test and for encoding.
+ * REQUIRES THREAD POOL
+ */
+public class SleepCallback extends StaticContentService {
+ long t1;
+ long t2;
+ long t3;
+ long t4;
+
+ public SleepCallback() {
+ }
+
+ public SleepCallback sleep(long t1, long t2, long t3,
+ long t4) {
+ this.t1 = t1;
+ this.t2 = t2;
+ this.t3 = t3;
+ this.t4 = t4;
+ return this;
+ }
+
+ public SleepCallback sleep(long t1) {
+ return sleep(t1, t1, t1, t1);
+ }
+
+ @Override
+ public void service(HttpRequest httpReq, HttpResponse res) throws IOException {
+ // TODO: blocking ! needs thread pool !
+ try {
+
+ Thread.currentThread().sleep(t1);
+ res.setStatus(200);
+ if (!chunked) {
+ res.setContentLength(mb.remaining() * 2);
+ }
+ res.setContentType(contentType);
+
+ res.sendHead();
+
+ Thread.currentThread().sleep(t2);
+
+ res.getBody().queue(BBuffer.wrapper(mb, 0, mb.remaining()));
+ res.flush();
+
+ //res.action(ActionCode.ACTION_CLIENT_FLUSH, res);
+
+ Thread.currentThread().sleep(t3);
+
+ res.getBody().queue(BBuffer.wrapper(mb, 0, mb.remaining()));
+ res.flush();
+
+ Thread.currentThread().sleep(t4);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.io;
+
+import org.apache.tomcat.lite.io.BBuffer;
+
+import junit.framework.TestCase;
+
+public class BBufferTest extends TestCase {
+ BBuffer res = BBuffer.wrapper("");
+
+ BBuffer l1 = BBuffer.wrapper("");
+ BBuffer l1a = BBuffer.wrapper("a");
+
+ BBuffer l2 = BBuffer.wrapper("\r");
+ BBuffer l3 = BBuffer.wrapper("\n");
+ BBuffer l4 = BBuffer.wrapper("\r\n");
+ BBuffer l5 = BBuffer.wrapper("\r\na");
+ BBuffer l5_a = BBuffer.wrapper("\ra");
+ BBuffer l5_b = BBuffer.wrapper("\na");
+ BBuffer l6 = BBuffer.wrapper("a\n");
+ BBuffer l7 = BBuffer.wrapper("GET \n");
+ BBuffer l8 = BBuffer.wrapper("GET /\n");
+ BBuffer l9 = BBuffer.wrapper("GET /a?b\n");
+ BBuffer l10 = BBuffer.wrapper("GET /a?b HTTP/1.0\n");
+ BBuffer l11 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b");
+ BBuffer l12 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\n");
+
+ BBuffer f1 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\n\n");
+ BBuffer f2 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\n\r\n");
+ BBuffer f3 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\r");
+ BBuffer f4 = BBuffer.wrapper("GET /a?b HTTP/1.0\na:b\r\n\r");
+
+ BBuffer s1 = BBuffer.wrapper(" \n");
+ BBuffer s2 = BBuffer.wrapper(" a");
+ BBuffer s3 = BBuffer.wrapper(" ");
+ BBuffer s4 = BBuffer.wrapper(" a");
+
+ BBuffer h1 = BBuffer.wrapper("a");
+ BBuffer h2 = BBuffer.wrapper("a?b");
+ BBuffer h3 = BBuffer.wrapper("a b");
+
+ public void hashTest(String s) {
+ assertEquals(s.hashCode(), BBuffer.wrapper(s).hashCode());
+ }
+
+ public void testHash() {
+ hashTest("");
+ hashTest("a");
+ hashTest("123abc");
+ hashTest("123abc\0");
+ // Fails for UTF chars - only ascii hashTest("123abc\u12345;");
+ }
+
+ public void testReadToSpace() {
+ assertEquals(3, l8.readToSpace(res));
+ assertEquals("GET", res.toString());
+ assertEquals(" /\n", l8.toString());
+
+ assertEquals(0, l1.readToSpace(res));
+ assertEquals("", res.toString());
+ assertEquals("", l1.toString());
+ }
+
+ public void testReadToDelim() {
+ assertEquals(1, h1.readToDelimOrSpace((byte)'?', res));
+ assertEquals("a", res.toString());
+ assertEquals("", h1.toString());
+
+ assertEquals(1, h2.readToDelimOrSpace((byte)'?', res));
+ assertEquals("a", res.toString());
+ assertEquals("?b", h2.toString());
+
+ assertEquals(1, h3.readToDelimOrSpace((byte)'?', res));
+ assertEquals("a", res.toString());
+ assertEquals(" b", h3.toString());
+ }
+
+ public void testGet() {
+ assertEquals(0x20, s1.get(0));
+ assertEquals(0x0a, s1.get(1));
+ try {
+ s1.get(2);
+ } catch(ArrayIndexOutOfBoundsException ex) {
+ return;
+ }
+ fail("Exception");
+ }
+
+ public void testSkipSpace() {
+ assertEquals(1, s1.skipSpace());
+ assertEquals("\n", s1.toString());
+
+ assertEquals(1, s2.skipSpace());
+ assertEquals("a", s2.toString());
+
+ assertEquals(2, s3.skipSpace());
+ assertEquals("", s3.toString());
+
+ assertEquals(3, s4.skipSpace());
+ assertEquals("a", s4.toString());
+
+ assertEquals(0, l1.skipSpace());
+ assertEquals("", l1.toString());
+ }
+
+ public void testLFLF() {
+ assertTrue(f1.hasLFLF());
+ assertTrue(f2.hasLFLF());
+ assertTrue(f3.hasLFLF());
+
+ assertFalse(f4.hasLFLF());
+ assertFalse(l1.hasLFLF());
+ assertFalse(l2.hasLFLF());
+ assertFalse(l3.hasLFLF());
+
+ assertFalse(l10.hasLFLF());
+ assertFalse(l11.hasLFLF());
+ assertFalse(l12.hasLFLF());
+ }
+
+ public void testReadLine() {
+ assertEquals(-1, l1.readLine(res));
+ assertEquals("", res.toString());
+ assertEquals("", l1.toString());
+
+ assertEquals(-1, l1a.readLine(res));
+ assertEquals("", res.toString());
+ assertEquals("a", l1a.toString());
+
+ assertEquals(0, l2.readLine(res));
+ assertEquals("", l2.toString());
+ assertEquals("", res.toString());
+ assertEquals(0, l3.readLine(res));
+ assertEquals("", l3.toString());
+ assertEquals("", res.toString());
+ assertEquals(0, l4.readLine(res));
+ assertEquals("", res.toString());
+
+ assertEquals(0, l5.readLine(res));
+ assertEquals("", res.toString());
+ assertEquals("a", l5.toString());
+ assertEquals(0, l5_b.readLine(res));
+ assertEquals("", res.toString());
+ assertEquals("a", l5_b.toString());
+ assertEquals(0, l5_a.readLine(res));
+ assertEquals("", res.toString());
+ assertEquals("a", l5_a.toString());
+
+ assertEquals(1, l6.readLine(res));
+ assertEquals("a", res.toString());
+
+ assertEquals(4, l7.readLine(res));
+ assertEquals("GET ", res.toString());
+ assertEquals(5, l8.readLine(res));
+ assertEquals("GET /", res.toString());
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.io;
+
+import junit.framework.TestCase;
+
+public class CBufferTest extends TestCase {
+
+ CBuffer ext = CBuffer.newInstance();
+
+ public void extTest(String path, String exp) {
+ CBuffer.newInstance().append(path).getExtension(ext, '/', '.');
+ assertEquals(exp, ext.toString());
+ }
+
+ public void testExt() {
+ extTest("foo.jsp", "jsp");
+ extTest("foo.j", "j");
+ extTest("/foo.j", "j");
+ extTest("//foo.j", "j");
+ extTest(".j", "j");
+ extTest(".", "");
+ extTest("/abc", "");
+ extTest("/abc.", "");
+ extTest("/abc/", "");
+ extTest("/abc/d", "");
+ }
+
+ public void testLastIndexOf() {
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.io;
+
+import java.io.IOException;
+
+import org.apache.tomcat.lite.TestMain;
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.io.MemoryIOConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector.MemoryIOChannel;
+
+import junit.framework.TestCase;
+
+public class OneTest extends TestCase {
+ MemoryIOConnector.MemoryIOChannel net = new MemoryIOChannel();
+ HttpChannel http = new HttpChannel()
+ .serverMode(true).withBuffers(net);
+
+ public void setUp() throws Exception {
+ TestMain.getTestServer();
+ }
+
+ public void tearDown() throws IOException {
+ }
+
+
+ public void testOne() throws Exception {
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.io;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tomcat.lite.proxy.SocksServer;
+
+
+import junit.framework.TestCase;
+
+public class SocksTest extends TestCase {
+
+ public void setUp() {
+// SocksServer socks = new SocksServer();
+// try {
+// socks.initServer();
+// } catch (IOException e1) {
+// // TODO Auto-generated catch block
+// e1.printStackTrace();
+// }
+//
+// ProxySelector.setDefault(new ProxySelector() {
+//
+// @Override
+// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+// }
+//
+// @Override
+// public List<Proxy> select(URI uri) {
+//
+// List<Proxy> res = new ArrayList<Proxy>();
+// try {
+// res.add(new Proxy(Proxy.Type.SOCKS,
+// new InetSocketAddress(InetAddress.getLocalHost(), 1080)));
+// } catch (UnknownHostException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// return res;
+// }
+//
+// });
+ }
+
+ public void testSocks() {
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.io;
+
+import junit.framework.TestCase;
+
+
+public class UEncoderTest extends TestCase {
+ IOWriter enc=new IOWriter(null);
+ UrlEncoding dec = new UrlEncoding();
+ CBuffer cc = CBuffer.newInstance();
+
+ /*
+ *
+ * Test method for 'org.apache.tomcat.util.buf.UEncoder.encodeURL(String)'
+ * TODO: find the relevant rfc and apache tests and add more
+ */
+ public void testEncodeURL() {
+
+ String eurl1=encodeURL("test");
+ assertEquals("test", eurl1);
+
+ eurl1=encodeURL("/test");
+ assertEquals("/test", eurl1);
+
+ // safe ranges
+ eurl1=encodeURL("test$-_.");
+ assertEquals("test$-_.", eurl1);
+
+ eurl1=encodeURL("test$-_.!*'(),");
+ assertEquals("test$-_.!*'(),", eurl1);
+
+ eurl1=encodeURL("//test");
+ assertEquals("//test", eurl1);
+ }
+
+ public String encodeURL(String uri) {
+ cc.recycle();
+ dec.urlEncode(uri, cc, enc);
+ return cc.toString();
+ }
+
+
+
+}
--- /dev/null
+RUN=Log,JMXProxy,Socks
+
+Log.(class)=org.apache.tomcat.integration.simple.LogConfig
+Log.debug=org.apache.tomcat.async.AsyncHttpConnector
+Log.debug=Proxy
+
+JMXProxy.(class)=org.apache.tomcat.integration.simple.JMXProxy
+JMXProxy.port=8003
+
+Socks.(class)=org.apache.tomcat.async.callbacks.SocksServer
+Socks.port=2080
+Socks.idleTimeout=0
+
+HttpConnector-TestServer.debug=true
+#HttpConnector-TestServer.debugHttp=true
+HttpConnector-TestServer.clientKeepAlive=true
+HttpConnector-TestServer.serverKeepAlive=true
+HttpConnector-TestServer.maxHttpPoolSize=10
+
+HttpConnector.debug=true
+#HttpConnector.debugHttp=true
+HttpConnector.clientKeepAlive=true
+HttpConnector.serverKeepAlive=true
+HttpConnector.maxHttpPoolSize=10
+
+HttpConnector-Proxy.debug=true
+#HttpConnector-Proxy.debugHttp=true
+HttpConnector-Proxy.clientKeepAlive=true
+HttpConnector-Proxy.serverKeepAlive=true
+HttpConnector-Proxy.maxHttpPoolSize=10
+
+
+#IOConnector.debug=true
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.load;
+
+import org.apache.tomcat.lite.http.LiveHttp1Test;
+
+import junit.framework.TestSuite;
+
+public class LiveHttp5Test extends LiveHttp1Test {
+
+ /**
+ * Want to run the same tests few times.
+ */
+ public static TestSuite suite() {
+ TestSuite s = new TestSuite();
+ for (int i = 0; i < 5; i++) {
+ s.addTestSuite(LiveHttp1Test.class);
+ }
+ return s;
+ }
+
+ public void test100() throws Exception {
+ for (int i = 0; i < 100; i++) {
+ testSimpleRequest();
+ tearDown();
+ setUp();
+
+ notFound();
+ tearDown();
+ setUp();
+
+ testSimpleRequest();
+ tearDown();
+ setUp();
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.load;
+
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.TestMain;
+import org.apache.tomcat.lite.http.DefaultHttpConnector;
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnector;
+import org.apache.tomcat.lite.http.HttpChannel.HttpService;
+import org.apache.tomcat.lite.http.HttpChannel.RequestCompleted;
+
+public class LiveHttpThreadedTest extends TestCase {
+ HttpConnector staticMain = TestMain.getTestServer();
+
+
+ int tCount = 1;
+ Thread[] threads = new Thread[tCount];
+ int[] ok = new int[tCount];
+ private int rCount = 100;
+
+ public void xtestSimpleRequest() throws Exception {
+ long t0 = System.currentTimeMillis();
+ for (int i = 0; i < tCount; i++) {
+ final int j = i;
+ threads[i] = new Thread(new Runnable() {
+ public void run() {
+ makeRequests(j, true);
+ }
+ });
+ threads[i].start();
+ }
+
+ int res = 0;
+ for (int i = 0; i < tCount; i++) {
+ threads[i].join();
+ res += ok[i];
+ }
+ long t1 = System.currentTimeMillis();
+ System.err.println("Time: " + (t1 - t0) + " " + res);
+ }
+
+ public void testSimpleRequestNB() throws Exception {
+ long t0 = System.currentTimeMillis();
+ for (int i = 0; i < tCount; i++) {
+ final int j = i;
+ threads[i] = new Thread(new Runnable() {
+ public void run() {
+ makeRequests(j, false);
+ }
+ });
+ threads[i].start();
+ }
+
+ int res = 0;
+ for (int i = 0; i < tCount; i++) {
+ threads[i].join();
+ res += ok[i];
+ }
+ long t1 = System.currentTimeMillis();
+ System.err.println("TimeNB: " + (t1 - t0) + " " + res);
+ }
+
+ void makeRequests(int t, boolean b) {
+ for (int i = 0; i < rCount ; i++) {
+ try {
+ //System.err.println("MakeReq " + t + " " + i);
+ makeRequest(t, b);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static RequestCompleted reqCallback = new RequestCompleted() {
+ @Override
+ public void handle(HttpChannel data, Object extraData)
+ throws IOException {
+ //dumpHead(cstate);
+ //System.err.println("DATA\n" + cstate.output.toString() + "\n----");
+ //assertTrue(cstate.bodyRecvBuffer.toString().indexOf("AAA") >= 0);
+
+ data.release();
+ }
+
+ };
+
+ void makeRequest(int i, boolean block) throws Exception {
+ HttpChannel cstate = DefaultHttpConnector.get().get("localhost", 8802);
+
+ cstate.getRequest().requestURI().set("/hello");
+ cstate.setCompletedCallback(reqCallback);
+
+ // Send the request, wait response
+ cstate.sendRequest();
+ }
+
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.load;
+
+import org.apache.tomcat.lite.http.BaseMapper;
+import org.apache.tomcat.lite.http.MappingData;
+import org.apache.tomcat.lite.io.CBuffer;
+
+import junit.framework.TestCase;
+
+public class MicroTest extends TestCase {
+
+ public void testMapper() throws Exception {
+ BaseMapper mapper = new BaseMapper();
+
+ MappingData mappingData = new MappingData();
+ CBuffer host = CBuffer.newInstance();
+ host.set("test1.com");
+
+ CBuffer uri = CBuffer.newInstance();
+ uri.set("/foo/bar/blah/bobou/foo");
+
+ String[] welcomes = new String[2];
+ welcomes[0] = "index.html";
+ welcomes[1] = "foo.html";
+
+ for (int i = 0; i < 100; i++) {
+ String hostN = "test" + i + ".com";
+ mapper.addContext(hostN, "", "context0", new String[0], null, null);
+ mapper.addContext(hostN, "/foo", "context1", new String[0], null, null);
+ mapper.addContext(hostN, "/foo/bar", "context2", welcomes, null, null);
+ mapper.addContext(hostN, "/foo/bar/bla", "context3", new String[0], null, null);
+
+ mapper.addWrapper(hostN, "/foo/bar", "/fo/*", "wrapper0");
+ }
+ int N = 10000;
+ for (int i = 0; i < N; i++) {
+ mappingData.recycle();
+ mapper.map(host, uri, mappingData);
+ }
+
+ long time = System.currentTimeMillis();
+ for (int i = 0; i < N; i++) {
+ mappingData.recycle();
+ mapper.map(host, uri, mappingData);
+ }
+ System.out.println("Elapsed:" + (System.currentTimeMillis() - time));
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.proxy;
+
+
+import java.io.IOException;
+
+import org.apache.tomcat.lite.http.LiveHttp1Test;
+
+
+public class LiveProxyHttp1Test extends LiveHttp1Test {
+ public void setUp() throws IOException {
+ // All tests in super, but with client pointing to
+ // the proxy server, which in turn hits the real server.
+ clientPort = 8903;
+ super.setUp();
+ }
+
+}
--- /dev/null
+/*
+n * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.proxy;
+
+import java.io.IOException;
+
+import org.apache.tomcat.lite.TestMain;
+
+import junit.framework.TestCase;
+
+
+public class ProxyTest extends TestCase {
+
+ String resStr;
+
+ public void setUp() throws Exception {
+ TestMain.getTestServer();
+ }
+
+ public void tearDown() throws IOException {
+ }
+
+ public void xtestRequestSlowChunked() throws Exception {
+ resStr =
+ TestMain.get("http://localhost:8903/sleep/1c").toString();
+ assertEquals("sleep 1csleep 1c", resStr);
+ }
+
+ public void testSingleRequest() throws Exception {
+ String resStr =
+ TestMain.get("http://localhost:8903/hello").toString();
+ assertEquals("Hello world", resStr);
+ }
+
+
+ public void test2Requests() throws Exception {
+ String resStr =
+ TestMain.get("http://localhost:8903/hello").toString();
+ assertEquals("Hello world", resStr);
+ resStr =
+ TestMain.get("http://localhost:8903/hello?a=b").toString();
+ assertEquals("Hello world", resStr);
+ }
+
+ public void testRequestSimple() throws Exception {
+ resStr =
+ TestMain.get("http://localhost:8903/hello").toString();
+ assertEquals("Hello world", resStr);
+ resStr =
+ TestMain.get("http://localhost:8903/hello").toString();
+ assertEquals("Hello world", resStr);
+ resStr =
+ TestMain.get("http://localhost:8903/hello").toString();
+ assertEquals(resStr, "Hello world");
+
+ }
+
+ public void testExtAdapter() throws Exception {
+ String res =
+ TestMain.get("http://www.apache.org/").toString();
+ assertTrue(res.indexOf("Apache") > 0);
+
+ Thread.currentThread().sleep(100);
+ // second time - are we reusing ?
+ res =
+ TestMain.get("http://www.apache.org/").toString();
+
+ assertTrue(res.indexOf("Apache") > 0);
+
+ }
+
+ public void testStaticAdapter() throws Exception {
+
+ assertEquals("Hello world",
+ TestMain.get("http://localhost:8802/hello").toString());
+ assertEquals("Hello world2",
+ TestMain.get("http://localhost:8802/2nd").toString());
+
+ }
+
+ public void testRequestParams() throws Exception {
+ // qry string
+ String resStr =
+ TestMain.get("http://localhost:8903/echo/foo?q=a&b")
+ .toString();
+ assertTrue(resStr, resStr.indexOf("foo?q=a&b") > 0);
+ }
+
+
+ public void testRequestChunked() throws Exception {
+ // Chunked encoding
+ String resStr =
+ TestMain.get("http://localhost:8903/chunked/test")
+ .toString();
+ assertEquals(8, resStr.length());
+ assertTrue(resStr.indexOf("AAA") >= 0);
+ }
+
+
+ public void testRequestSlow() throws Exception {
+ // Slow
+ String resStr =
+ TestMain.get("http://localhost:8903/sleep/1").toString();
+ assertEquals("sleep 1sleep 1", resStr.toString());
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.proxy;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector.MemoryIOChannel;
+
+public class SmallProxyTest extends TestCase {
+
+ MemoryIOConnector memoryServerConnector =
+ new MemoryIOConnector();
+
+ MemoryIOConnector memoryClientConnector =
+ new MemoryIOConnector().withServer(memoryServerConnector);
+
+
+ HttpConnector httpPool = new HttpConnector(memoryServerConnector) {
+ @Override
+ public HttpChannel get(CharSequence target) throws IOException {
+ throw new IOException();
+ }
+ public HttpChannel getServer() {
+ lastServer = new HttpChannel().serverMode(true);
+ lastServer.withBuffers(net);
+ lastServer.setConnector(this);
+ //lastServer.withIOConnector(memoryServerConnector);
+ return lastServer;
+ }
+ };
+
+ HttpConnector httpClient = new HttpConnector(memoryClientConnector) {
+ @Override
+ public HttpChannel get(CharSequence target) throws IOException {
+ lastClient = new HttpChannel();
+ lastClient.setConnector(this);
+ return lastClient;
+ }
+ public HttpChannel get(String host, int port) throws IOException {
+ lastClient = new HttpChannel();
+ lastClient.setConnector(this);
+ return lastClient;
+ }
+ public HttpChannel getServer() {
+ throw new RuntimeException();
+ }
+ };
+
+ HttpChannel lastServer;
+ HttpChannel lastClient;
+
+ boolean hasBody = false;
+ boolean bodyDone = false;
+ boolean bodySentDone = false;
+ boolean headersDone = false;
+ boolean allDone = false;
+
+
+ //MemoryIOChannel clientNet = new MemoryIOChannel();
+
+ MemoryIOConnector.MemoryIOChannel net = new MemoryIOChannel();
+ HttpChannel http;
+
+ public void setUp() throws IOException {
+ http = httpPool.getServer();
+ }
+
+ /**
+ * More complicated test..
+ * @throws IOException
+ */
+ public void testProxy() throws IOException {
+ http.setHttpService(new HttpProxyService()
+ .withSelector(memoryClientConnector)
+ .withHttpClient(httpClient));
+
+ http.getNet().getIn().append("GET http://www.cyberluca.com/ HTTP/1.0\n" +
+ "Connection: Close\n\n");
+ http.getNet().getIn().close();
+
+ // lastClient.rawSendBuffers has the request sent by proxy
+ lastClient.getNet().getIn()
+ .append("HTTP/1.0 200 OK\n\nHi\n");
+ lastClient.getNet().getIn()
+ .append("world\n");
+
+ // TODO: check what the proxy sent
+ // lastClient.getOut();
+
+ // will also trigger 'release' - both sides are closed.
+ lastClient.getNet().getIn().close();
+
+ // wait response...
+ // http.sendBody.close();
+ String res = net.out.toString();
+ assertTrue(res.indexOf("Hi\nworld\n") > 0);
+ assertTrue(res.indexOf("HTTP/1.0 200 OK") == 0);
+ assertTrue(res.indexOf("tomcatproxy") > 0);
+
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.servlet;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.servlets.config.ServletContextConfig;
+import org.apache.tomcat.servlets.config.deploy.AnnotationsProcessor;
+
+public class AnnotationTest extends TestCase {
+
+ // TODO: fix the build file to find the target dir
+ // you can run this manually until this happens
+ String eclipseBase = "test-webapp/WEB-INF/classes";
+
+ public void testScanClasses() throws IOException {
+ ServletContextConfig cfg = new ServletContextConfig();
+ AnnotationsProcessor scanner = new AnnotationsProcessor(cfg);
+// scanner.processDir(eclipseBase);
+//
+// dump(cfg);
+
+ }
+
+ public void testScanClass() throws IOException {
+ ServletContextConfig cfg = new ServletContextConfig();
+ AnnotationsProcessor scanner = new AnnotationsProcessor(cfg);
+
+ String path = eclipseBase + "/org/apache/tomcat/lite/Annotated2Servlet.class";
+// scanner.processClass(new FileInputStream(path), eclipseBase, path);
+//
+// dump(cfg);
+
+ }
+
+ private void dump(ServletContextConfig cfg) {
+// ObjectMapper jackson = new ObjectMapper();
+// try {
+// jackson.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+// jackson.configure(SerializationConfig.Feature.WRITE_NULL_PROPERTIES,
+// false);
+//
+// ByteArrayOutputStream out = new ByteArrayOutputStream();
+// jackson.writeValue(out, cfg);
+// System.err.println(out.toString());
+// } catch (Throwable t) {
+// t.printStackTrace();
+// }
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.servlet;
+
+
+import org.apache.tomcat.lite.servlet.TomcatLite;
+
+import junit.framework.Test;
+
+public class JspWatchdogTests extends TomcatLiteWatchdog {
+
+ public JspWatchdogTests() {
+ super();
+ testMatch =
+ //"precompileNegativeTest";
+ null;
+ // Test we know are failing - need to fix at some point.
+ exclude = new String[] {
+ "negativeDuplicateExtendsFatalTranslationErrorTest",
+ "negativeDuplicateErrorPageFatalTranslationErrorTest",
+ "negativeDuplicateInfoFatalTranslationErrorTest",
+ "negativeDuplicateLanguageFatalTranslationErrorTest",
+ "negativeDuplicateSessionFatalTranslationErrorTest",
+ "positiveIncludeCtxRelativeHtmlTest",
+ "precompileNegativeTest"
+ };
+ file = getWatchdogdir() + "/src/conf/jsp-gtest.xml";
+ goldenDir =
+ getWatchdogdir() + "/src/clients/org/apache/jcheck/jsp/client/";
+ targetMatch = "jsp-test";
+
+ }
+
+ protected void addConnector(TomcatLite lite) {
+ lite.setPort(8019);
+ }
+
+ public static Test suite() {
+ return new JspWatchdogTests().getSuite(8019);
+ }
+
+}
+
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.servlet;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.servlet.ServletContextImpl;
+import org.apache.tomcat.lite.servlet.TomcatLite;
+
+public class LiteTestHelper {
+ static TomcatLite lite;
+
+ public static ServletContextImpl addContext(TomcatLite lite) throws ServletException {
+ ServletContextImpl ctx =
+ (ServletContextImpl) lite.addServletContext(null, null, "/test1");
+
+
+ ctx.add("testException", new HttpServlet() {
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws IOException {
+ throw new NullPointerException();
+ }
+ });
+ ctx.addMapping("/testException", "testException");
+
+
+ ctx.add("test", new HttpServlet() {
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
+ res.addHeader("Foo", "Bar");
+ res.getWriter().write("Hello world");
+ }
+ });
+
+ ctx.addMapping("/1stTest", "test");
+
+
+ return ctx;
+ }
+
+ public static void startLite() throws IOException, ServletException {
+ if (lite == null) {
+ lite = new TomcatLite();
+
+ LiteTestHelper.addContext(lite);
+ lite.start();
+
+ lite.startConnector();
+ }
+ }
+
+ public static void initServletsAndRun(TomcatLite lite, int port) throws ServletException, IOException {
+ addContext(lite);
+ lite.init();
+ lite.start();
+
+
+ if (port > 0) {
+ // This should be added after all local initialization to avoid
+ // the server from responding.
+ // Alternatively, you can load this early but set it to return
+ // 'unavailable' if load balancers depend on this.
+ addConnector(lite, port, true);
+
+ // At this point we can add contexts and inject requests, if we want to
+ // do it over HTTP need to start the connector as well.
+ lite.startConnector();
+ }
+ }
+
+ public static void addConnector(TomcatLite lite,
+ int port, boolean daemon) {
+ lite.setPort(port);
+ }
+
+ /**
+ * Get url using URLConnection.
+ */
+ public static BBuffer getUrl(String path) throws IOException {
+
+ BBuffer out = BBuffer.allocate(4096);
+
+ URL url = new URL(path);
+ URLConnection connection = url.openConnection();
+ connection.setReadTimeout(5000);
+ connection.connect();
+ InputStream is = connection.getInputStream();
+ out.readAll(is);
+ return out;
+ }
+
+// static class ByteChunkOutputBuffer implements OutputBuffer {
+//
+// protected ByteChunk output = null;
+//
+// public ByteChunkOutputBuffer(ByteChunk output) {
+// this.output = output;
+// }
+//
+// public int doWrite(ByteChunk chunk, Response response)
+// throws IOException {
+// output.append(chunk);
+// return chunk.getLength();
+// }
+// }
+
+
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.servlet;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.integration.simple.SimpleObjectManager;
+
+
+public class PropertiesSpiTest extends TestCase {
+
+ SimpleObjectManager spi;
+
+ public void setUp() {
+ spi = new SimpleObjectManager();
+
+ spi.getProperties().put("obj1.name", "foo");
+ spi.getProperties().put("obj1.(class)", BoundObj.class.getName());
+
+ }
+
+ public void testArgs() throws IOException {
+ spi = new SimpleObjectManager(new String[] {
+ "-a=1", "-b", "2"});
+ Properties res = spi.getProperties();
+
+ assertEquals("1", res.get("a"));
+ assertEquals("2", res.get("b"));
+
+
+ }
+
+ public static class BoundObj {
+ String name;
+
+ public void setName(String n) {
+ this.name = n;
+ }
+ }
+
+ public void testBind() throws Exception {
+ BoundObj bo = new BoundObj();
+ spi.bind("obj1", bo);
+ assertEquals(bo.name, "foo");
+ }
+
+ public void testCreate() throws Exception {
+ BoundObj bo = (BoundObj) spi.get("obj1");
+ assertEquals(bo.name, "foo");
+ }
+}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.lite.servlet;
+
+import org.apache.tomcat.lite.servlet.TomcatLite;
+
+import junit.framework.Test;
+
+public class ServletTests extends TomcatLiteWatchdog {
+
+ public ServletTests() {
+ super();
+ exclude = new String[] {
+ "ServletToJSPErrorPageTest",
+ "ServletToJSPError502PageTest",
+ };
+ }
+
+ protected void addConnector(TomcatLite connector) {
+ connector.setPort(7074);
+ }
+
+ /**
+ * Magic JUnit method
+ */
+ public static Test suite() {
+ return new ServletTests().getSuite(7074);
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.servlet;
+
+
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnector;
+import org.apache.tomcat.lite.http.HttpRequest;
+import org.apache.tomcat.lite.http.HttpResponse;
+import org.apache.tomcat.lite.io.BBuffer;
+import org.apache.tomcat.lite.io.MemoryIOConnector;
+import org.apache.tomcat.lite.io.MemoryIOConnector.MemoryIOChannel;
+import org.apache.tomcat.lite.servlet.TomcatLite;
+
+/**
+ * Example of testing servlets without using sockets.
+ *
+ * @author Costin Manolache
+ */
+public class TomcatLiteNoConnectorTest extends TestCase {
+
+ TomcatLite lite;
+ MemoryIOConnector net;
+ HttpConnector con;
+
+ public void setUp() throws Exception {
+ net = new MemoryIOConnector();
+ con = new HttpConnector(net);
+
+ lite = new TomcatLite();
+ lite.setHttpConnector(con);
+
+ // Load all servlets we need to test
+ LiteTestHelper.initServletsAndRun(lite, 0);
+ }
+
+ public void tearDown() throws Exception {
+ lite.stop();
+ }
+
+
+ public void testSimpleRequest() throws Exception {
+ MemoryIOConnector.MemoryIOChannel ch = new MemoryIOChannel();
+
+ HttpChannel httpCh = con.getServer();
+ httpCh.withBuffers(ch);
+
+ HttpRequest req = httpCh.getRequest();
+ req.setURI("/test1/1stTest");
+
+ HttpResponse res = httpCh.getResponse();
+
+ lite.getHttpConnector().getDispatcher().service(req, res, true);
+ // req/res will be recycled
+
+ // parse out to a response
+ BBuffer out = ch.out;
+ MemoryIOChannel clientCh = new MemoryIOChannel();
+ clientCh.getIn().append(out);
+
+ HttpChannel client = con.get("localhost", 80);
+ client.withBuffers(clientCh);
+ clientCh.handleReceived(clientCh);
+
+
+ HttpResponse cres = client.getResponse();
+ assertEquals(res.getStatus(), 200);
+
+ BBuffer resBody = BBuffer.allocate(200);
+ cres.getBody().readAll(resBody);
+ assertEquals("Hello world", resBody.toString());
+ assertEquals(cres.getHeader("Foo"), "Bar");
+ assertEquals(cres.getStatus(), 200);
+ }
+
+//
+// public void testPostRequest() throws Exception {
+// ByteChunk out = new ByteChunk();
+// ServletRequestImpl req =
+// LiteTestHelper.createMessage(lite, "/test1/1stTest", out);
+// req.setMethod("POST");
+//
+// ServletResponseImpl res = lite.service(req);
+//
+// assertEquals("Hello post world", out.toString());
+// // Headers are still in the response
+// assertEquals(res.getHeader("Foo"), "Post");
+// assertEquals(res.getStatus(), 200);
+// }
+//
+// public void testException() throws IOException, Exception {
+// ByteChunk out = new ByteChunk();
+// ServletRequestImpl req =
+// LiteTestHelper.createMessage(lite, "/test1/testException", out);
+// ServletResponseImpl res = lite.service(req);
+// assertEquals(res.getStatus(), 500);
+// }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.servlet;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import junit.framework.TestCase;
+
+import org.apache.tomcat.lite.io.IOBuffer;
+
+/**
+ * TODO: convert to new API
+ *
+ */
+public class TomcatLiteSimpleTest extends TestCase {
+
+ protected TomcatLite lite = new TomcatLite();
+
+ public void setUp() throws Exception {
+ LiteTestHelper.addContext(lite);
+
+ lite.init();
+
+ lite.setPort(8884);
+ lite.start();
+ lite.startConnector();
+ }
+
+ public void testSimpleRequest() throws Exception {
+ URL url = new URL("http://localhost:8884/test1/1stTest");
+ URLConnection connection = url.openConnection();
+ InputStream is = connection.getInputStream();
+ String res = new IOBuffer().append(is).readAll(null).toString();
+ assertEquals("Hello world", res);
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite.servlet;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import junit.framework.TestResult;
+
+import org.apache.tomcat.lite.servlet.TomcatLite;
+import org.apache.tomcat.test.watchdog.WatchdogClient;
+
+
+public abstract class TomcatLiteWatchdog extends WatchdogClient {
+
+ public TomcatLiteWatchdog() {
+ goldenDir = getWatchdogdir() + "/src/clients/org/apache/jcheck/servlet/client/";
+ testMatch =
+ //"HttpServletResponseWrapperSetStatusMsgTest";
+ //"ServletContextAttributeAddedEventTest";
+ null;
+ // ex: "ServletToJSP";
+ file = getWatchdogdir() + "/src/conf/servlet-gtest.xml";
+ targetMatch = "gtestservlet-test";
+ }
+
+ protected void beforeSuite() {
+ // required for the tests
+ System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER",
+ "true");
+
+ try {
+ initServerWithWatchdog(getWatchdogdir());
+ } catch (ServletException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected abstract void addConnector(TomcatLite liteServer);
+
+ TomcatLite tomcatForWatchdog;
+
+ public void initServerWithWatchdog(String wdDir) throws ServletException,
+ IOException {
+ File f = new File(wdDir + "/build/webapps");
+
+ tomcatForWatchdog = new TomcatLite();
+
+ addConnector(tomcatForWatchdog);
+// tomcatForWatchdog.getHttpConnector().setDebug(true);
+// tomcatForWatchdog.getHttpConnector().setDebugHttp(true);
+
+ tomcatForWatchdog.addServletContext(null, "webapps/ROOT", "/").loadConfig();
+
+ for (String s : new String[] {
+ "servlet-compat",
+ "servlet-tests",
+ "jsp-tests"} ) {
+ tomcatForWatchdog.addServletContext(null, f.getCanonicalPath() + "/" + s,
+ "/" + s).loadConfig();
+ }
+
+ tomcatForWatchdog.init();
+ tomcatForWatchdog.start();
+
+ tomcatForWatchdog.startConnector();
+ }
+
+
+
+ protected void afterSuite(TestResult res) {
+ // no need to stop it - using daemon threads.
+ }
+}
--- /dev/null
+RUN=Log,JMXProxy,Socks,TomcatLite
+
+Log.(class)=org.apache.tomcat.lite.service.LogConfig
+Log.debug=org.apache.tomcat.lite.http.HttpConnector
+Log.debug=Proxy
+
+JMXProxy.(class)=org.apache.tomcat.lite.service.JMXProxy
+JMXProxy.port=8003
+
+Socks.(class)=org.apache.tomcat.lite.proxy.SocksServer
+Socks.port=2080
+Socks.idleTimeout=0
+
+#HttpConnector-TestServer.debug=true
+#HttpConnector-TestServer.debugHttp=true
+xHttpConnector-TestServer.clientKeepAlive=true
+xHttpConnector-TestServer.serverKeepAlive=true
+xHttpConnector-TestServer.maxHttpPoolSize=0
+
+#HttpConnector.debug=true
+#HttpConnector.debugHttp=true
+xHttpConnector.clientKeepAlive=true
+xHttpConnector.serverKeepAlive=true
+xHttpConnector.maxHttpPoolSize=0
+
+#HttpConnector-Proxy.debug=true
+#HttpConnector-Proxy.debugHttp=true
+xHttpConnector-Proxy.clientKeepAlive=true
+xHttpConnector-Proxy.serverKeepAlive=true
+xHttpConnector-Proxy.maxHttpPoolSize=0
+
+
+#IOConnector.debug=true
+
+# Tomcat-lite config
+# include:
+# config=org/apache/tomcat/lite/config.properties
+TomcatLite.(class)=org.apache.tomcat.lite.servlet.TomcatLite
+# TomcatLite.deployListener=org.apache.tomcat.servlets.config.deploy.WebXmlContextListener
+
+# Tomcat-lite plugins
+org.apache.tomcat.lite.WebappServletMapper.(class)=org.apache.tomcat.lite.WebappServletMapper
+org.apache.tomcat.lite.WebappFilterMapper.(class)=org.apache.tomcat.lite.WebappFilterMapper
+org.apache.tomcat.servlets.session.UserSessionManager.(class)=org.apache.tomcat.servlets.session.SimpleSessionManager
+org.apache.tomcat.servlets.jsp.UserTemplateClassMapper.(class)=org.apache.tomcat.servlets.jsp.JasperCompilerTemplateClassMapper
+org.apache.tomcat.servlets.file.Filesystem.(class)=org.apache.tomcat.file.LocalFilesystem
+default-servlet.(class)=org.apache.tomcat.servlets.file.WebdavServlet
+jspwildcard-servlet.(class)=org.apache.tomcat.servlets.jsp.WildcardTemplateServlet
+filetemplate-servlet.(class)=org.apache.tomcat.servlets.jsp.JspFileTemplateServlet
+
+org.apache.tomcat.lite.Connector.(class)=org.apache.tomcat.lite.AsyncConnector
+org.apache.tomcat.lite.Connector.port=8800
+
+
+
+TomcatLite.context.1=/examples:./webapps/examples
+TomcatLite.context.2=/:./webapps/ROOT
+TomcatLite.context.3=/lite:./modules/tomcat-lite/test-webapp
+// No base dir
+TomcatLite.context.4=/dynamic:
+
+
+JMXProxyServlet.(class)=org.apache.tomcat.integration.jmx.JMXProxyServlet
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @Author Costin, Ramesh.Mandava
-*/
-
-package org.apache.tomcat.test.watchdog;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.apache.tomcat.lite.HexDump;
-import org.apache.tools.ant.BuildException;
-
-
-// derived from Jsp
-
-public class GTest {
-
- int failureCount = 0;
- int passCount = 0;
- Throwable lastError;
- boolean hasFailed = false;
-
- String prefix = "http";
- String host = "localhost";
- String localHost = null;
- String localIP = null;
- int port = 8080;
- int debug = 0;
-
- String description = "No description";
-
- String request;
- HashMap requestHeaders = new HashMap();
- String content;
-
- // true if task is nested
- private boolean nested = false;
-
- // Expected response
- boolean magnitude = true;
- boolean exactMatch = false;
-
- // expect a response body
- boolean expectResponseBody = true;
-
- // Match the body against a golden file
- String goldenFile;
- // Match the body against a string
- String responseMatch;
- // the response should include the following headers
- HashMap expectHeaders = new HashMap();
-
- // Headers that should not be found in response
- HashMap unexpectedHeaders = new HashMap();
-
- // Match request line
- String returnCode = "";
- String returnCodeMsg = "";
-
- // Actual response
- String responseLine;
- byte[] responseBody;
- HashMap headers;
-
-
- // For Report generation
- StringBuilder resultOut = new StringBuilder();
-
- boolean firstTask = false;
- boolean lastTask = false;
- String expectedString;
- String actualString;
-
- String testName;
- String assertion;
- String testStrategy;
-
- // For Session Tracking
- static Hashtable sessionHash;
- static Hashtable cookieHash;
-
- String testSession;
- Vector cookieVector;
- URL requestURL;
- CookieController cookieController ;
-
- /**
- * Creates a new <code>GTest</code> instance.
- *
- */
- public GTest() {
- }
-
- /**
- * <code>setTestSession</code> adds a
- * CookieController for the value of sessionName
- *
- * @param sessionName a <code>String</code> value
- */
- public void setTestSession( String sessionName ) {
- testSession = sessionName;
-
- if ( sessionHash == null ) {
- sessionHash = new Hashtable();
- } else if ( sessionHash.get( sessionName ) == null ) {
- sessionHash.put ( sessionName, new CookieController() );
- }
- }
-
- /**
- * <code>setTestName</code> sets the current test name.
- *
- * @param tn current testname.
- */
- public void setTestName ( String tn ) {
- testName = tn;
- }
-
- /**
- * <code>setAssertion</code> sets the assertion text
- * for the current test.
- *
- * @param assertion assertion text
- */
- public void setAssertion ( String assertion ) {
- this.assertion = assertion;
- }
-
- /**
- * <code>setTestStrategy</code> sets the test strategy
- * for the current test.
- *
- * @param strategy test strategy text
- */
- public void setTestStrategy ( String strategy ) {
- testStrategy = strategy;
- }
-
- /**
- * <code>getTestName</code> returns the current
- * test name.
- *
- * @return a <code>String</code> value
- */
- public String getTestName( ) {
- return testName;
- }
-
- /**
- * <code>getAssertion</code> returns the current
- * assertion text.
- *
- * @return a <code>String</code> value
- */
- public String getAssertion( ) {
- return assertion;
- }
-
- /**
- * <code>getTestStrategy</code> returns the current
- * test strategy test.
- *
- * @return a <code>String</code> value
- */
- public String getTestStrategy( ) {
- return testStrategy;
- }
-
- /**
- * <code>setFirstTask</code> denotes that current task
- * being executed is the first task within the list.
- *
- * @param a <code>boolean</code> value
- */
- public void setFirstTask( boolean val ) {
- firstTask = val;
- }
-
-
- /**
- * <code>setLastTask</code> denotes that the current task
- * being executed is the last task within the list.
- *
- * @param a <code>boolean</code> value
- */
- public void setLastTask ( boolean val ) {
- lastTask = val;
- }
-
- /**
- * <code>setPrefix</code> sets the protocol
- * prefix. Defaults to "http"
- *
- * @param prefix Either http or https
- */
- public void setPrefix( String prefix ) {
- this.prefix = prefix;
- }
-
- /**
- * <code>setHost</code> sets hostname where
- * the target server is running. Defaults to
- * "localhost"
- *
- * @param h a <code>String</code> value
- */
- public void setHost( String h ) {
- this.host = h;
- }
-
- /**
- * <code>setPort</code> sets the port
- * that the target server is listening on.
- * Defaults to "8080"
- *
- * @param portS a <code>String</code> value
- */
- public void setPort( String portS ) {
- this.port = Integer.valueOf( portS ).intValue();
- }
-
- /**
- * <code>setExactMatch</code> determines if a
- * byte-by-byte comparsion is made of the server's
- * response and the test's goldenFile, or if
- * a token comparison is made. By default, only
- * a token comparison is made ("false").
- *
- * @param exact a <code>String</code> value
- */
- public void setExactMatch( String exact ) {
- exactMatch = Boolean.valueOf( exact ).booleanValue();
- }
-
- /**
- * <code>setContent</code> String value upon which
- * the request header Content-Length is based upon.
- *
- * @param s a <code>String</code> value
- */
- public void setContent( String s ) {
- this.content = s;
- }
-
- /**
- * <code>setDebug</code> enables debug output.
- * By default, this is disabled ( value of "0" ).
- *
- * @param debugS a <code>String</code> value
- */
- public void setDebug( String debugS ) {
- debug = Integer.valueOf( debugS ).intValue();
- }
-
- /**
- * <code>setMagnitude</code> Expected return
- * value of the test execution.
- * Defaults to "true"
- *
- * @param magnitudeS a <code>String</code> value
- */
- public void setMagnitude( String magnitudeS ) {
- magnitude = Boolean.valueOf( magnitudeS ).booleanValue();
- }
-
- /**
- * <code>setGoldenFile</code> Sets the goldenfile
- * that will be used to validate the server's response.
- *
- * @param s fully qualified path and filename
- */
- public void setGoldenFile( String s ) {
- this.goldenFile = s;
- }
-
- /**
- * <code>setExpectResponseBody</code> sets a flag
- * to indicate if a response body is expected from the
- * server or not
- *
- * @param b a <code>boolean</code> value
- */
- public void setExpectResponseBody( boolean b ) {
- this.expectResponseBody = b;
- }
-
- /**
- * <code>setExpectHeaders</code> Configures GTest
- * to look for the header passed in the server's
- * response.
- *
- * @param s a <code>String</code> value in the
- * format of <header-field>:<header-value>
- */
- public void setExpectHeaders( String s ) {
- this.expectHeaders = new HashMap();
- StringTokenizer tok = new StringTokenizer( s, "|" );
- while ( tok.hasMoreElements() ) {
- String header = (String) tok.nextElement();
- setHeaderDetails( header, expectHeaders, false );
- }
- }
-
- /**
- * <code>setUnexpectedHeaders</code> Configures GTest
- * to look for the header passed to validate that it
- * doesn't exist in the server's response.
- *
- * @param s a <code>String</code> value in the
- * format of <header-field>:<header-value>
- */
- public void setUnexpectedHeaders( String s ) {
- this.unexpectedHeaders = new HashMap();
- setHeaderDetails( s, unexpectedHeaders, false );
- }
-
- public void setNested( String s ) {
- nested = Boolean.valueOf( s ).booleanValue();
- }
-
- /**
- * <code>setResponseMatch</code> Match the
- * passed value in the server's response.
- *
- * @param s a <code>String</code> value
- */
- public void setResponseMatch( String s ) {
- this.responseMatch = s;
- }
-
- /**
- * <code>setRequest</code> Sets the HTTP/HTTPS
- * request to be sent to the target server
- * Ex.
- * GET /servlet_path/val HTTP/1.0
- *
- * @param s a <code>String</code> value in the form
- * of METHOD PATH HTTP_VERSION
- */
- public void setRequest ( String s ) {
- this.request = s;
- }
-
- /**
- * <code>setReturnCode</code> Sets the expected
- * return code from the server's response.
- *
- * @param code a valid HTTP response status code
- */
- public void setReturnCode( String code ) {
- this.returnCode = code;
- }
-
- /**
- * Describe <code>setReturnCodeMsg</code> Sets the expected
- * return message to be found in the server's
- * response.
- *
- * @param code a valid HTTP resonse status code
- * @param message a <code>String</code> value
- */
- public void setReturnCodeMsg( String message ) {
- this.returnCodeMsg = message;
- }
-
- /**
- * <code>setRequestHeaders</code> Configures the request
- * headers GTest should send to the target server.
- *
- * @param s a <code>String</code> value in for format
- * of <field-name>:<field-value>
- */
- public void setRequestHeaders( String s ) {
- requestHeaders = new HashMap();
- StringTokenizer tok = new StringTokenizer( s, "|" );
- while ( tok.hasMoreElements() ) {
- String header = (String) tok.nextElement();
- setHeaderDetails( header, requestHeaders, true );
- }
- }
-
- // Inner tests are not used currently, can be reworked
-
-// /**
-// * Add a Task to this container
-// *
-// * @param Task to add
-// */
-// public void addTask(Task task) {
-// children.add(task);
-// }
-
- /**
- * <code>execute</code> Executes the test.
- *
- * @exception BuildException if an error occurs
- */
- public void execute() {
-
- try {
-
- if ( resultOut != null && !nested ) {
- resultOut.append("\ntestName: " + testName);
- resultOut.append("\nreq: " + request);
- resultOut.append("\nassertion: " + assertion);
- resultOut.append("\ntestStrategy: " + testStrategy);
- }
-
- WatchdogHttpClient.dispatch(this);
-
- hasFailed = !checkResponse( magnitude );
-
-
-// if ( !children.isEmpty() ) {
-// Iterator iter = children.iterator();
-// while (iter.hasNext()) {
-// Task task = (Task) iter.next();
-// task.perform();
-// }
-// }
-
- if ( !hasFailed && !nested ) {
- passCount++;
- if ( resultOut != null ) {
- resultOut.append( "<result>PASS</result>\n" );
- }
- System.out.println( " PASSED " + testName + "\n (" + request + ")" );
- } else if ( hasFailed && !nested ){
- failureCount++;
- if ( resultOut != null ) {
- resultOut.append( "<result>FAIL</result>\n" );
- }
- System.out.println( " FAILED " + testName + "\n (" + request + ")\n" +
- resultOut.toString());
- }
-
- } catch ( Exception ex ) {
- failureCount++;
- System.out.println( " FAIL " + description + " (" + request + ")" );
- lastError = ex;
- ex.printStackTrace();
- } finally {
- if ( !nested ) {
- hasFailed = false;
- }
- }
- }
-
- /**
- * <code>checkResponse</code> Executes various response
- * checking mechanisms against the server's response.
- * Checks include:
- * <ul>
- * <li>expected headers
- * <li>unexpected headers
- * <li>return codes and messages in the Status-Line
- * <li>response body comparison againt a goldenfile
- * </ul>
- *
- * @param testCondition a <code>boolean</code> value
- * @return a <code>boolean</code> value
- * @exception Exception if an error occurs
- */
- private boolean checkResponse( boolean testCondition )
- throws Exception {
- boolean match = false;
-
- if ( responseLine != null ) {
- // If returnCode doesn't match
- if ( responseLine.indexOf( "HTTP/1." ) > -1 ) {
-
- if ( !returnCode.equals( "" ) ) {
- boolean resCode = ( responseLine.indexOf( returnCode ) > -1 );
- boolean resMsg = ( responseLine.indexOf( returnCodeMsg ) > -1 );
-
- if ( returnCodeMsg.equals( "" ) ) {
- match = resCode;
- } else {
- match = ( resCode && resMsg );
- }
-
- if ( match != testCondition ) {
-
- if ( resultOut != null ) {
- String expectedStatusCode = "<expectedStatusCode>" + returnCode + "</expectedReturnCode>\n";
- String expectedReasonPhrase = "<expectedReasonPhrase>" + returnCodeMsg + "</expectedReasonPhrase>";
- actualString = "<actualStatusLine>" + responseLine + "</actualStatusLine>\n";
- resultOut.append( expectedStatusCode );
- resultOut.append( expectedReasonPhrase );
- resultOut.append( actualString );
- }
-
- return false;
- }
- }
- } else {
- resultOut.append("\n<failure>Wrong Http version: " + responseLine +
- "</failure>");
- return false;
- }
- } else {
- resultOut.append("\n<failure>No response from server</failure>" );
- return false;
- }
-
- /*
- * Check for headers the test expects to be in the server's response
- */
-
- // Duplicate set of response headers
- HashMap copiedHeaders = cloneHeaders( headers );
-
- // used for error reporting
- String currentHeaderField = null;
- String currentHeaderValue = null;
-
- if ( !expectHeaders.isEmpty() ) {
- boolean found = false;
- String expHeader = null;
-
- if ( !headers.isEmpty() ) {
- Iterator expectIterator = expectHeaders.keySet().iterator();
- while ( expectIterator.hasNext() ) {
- found = false;
- String expFieldName = (String) expectIterator.next();
- currentHeaderField = expFieldName;
- ArrayList expectValues = (ArrayList) expectHeaders.get( expFieldName );
- Iterator headersIterator = copiedHeaders.keySet().iterator();
-
- while( headersIterator.hasNext() ) {
- String headerFieldName = (String) headersIterator.next();
- ArrayList headerValues = (ArrayList) copiedHeaders.get( headerFieldName );
-
- // compare field names and values in an HTTP 1.x compliant fashion
- if ( ( headerFieldName.equalsIgnoreCase( expFieldName ) ) ) {
- int hSize = headerValues.size();
- int eSize = expectValues.size();
-
- // number of expected headers found in server response
- int numberFound = 0;
-
- for ( int i = 0; i < eSize; i++ ) {
- currentHeaderValue = (String) expectValues.get( i );
-
- /*
- * Handle the Content-Type header appropriately
- * based on the the test is configured to look for.
- */
- if ( currentHeaderField.equalsIgnoreCase( "content-type" ) ) {
- String resVal = (String) headerValues.get( 0 );
- if ( currentHeaderValue.indexOf( ';' ) > -1 ) {
- if ( currentHeaderValue.equals( resVal ) ) {
- numberFound++;
- headerValues.remove( 0 );
- }
- } else if ( resVal.indexOf( currentHeaderValue ) > -1 ) {
- numberFound++;
- headerValues.remove( 0 );
- }
- } else if ( currentHeaderField.equalsIgnoreCase( "location" ) ) {
- String resVal = (String) headerValues.get( 0 );
- int idx = currentHeaderValue.indexOf( ":80/" );
- if ( idx > -1 ) {
- String tempValue = currentHeaderValue.substring( 0, idx ) +
- currentHeaderValue.substring( idx + 3 );
- if ( currentHeaderValue.equals( resVal ) ||
- tempValue.equals( resVal ) ) {
- numberFound++;
- headerValues.remove( 0 );
- }
- } else {
- if ( currentHeaderValue.equals( resVal ) ) {
- numberFound++;
- headerValues.remove( 0 );
- }
- }
- } else if ( headerValues.contains( currentHeaderValue ) ) {
- numberFound++;
- headerValues.remove( headerValues.indexOf( currentHeaderValue ) );
- }
- }
- if ( numberFound == eSize ) {
- found = true;
- }
- }
- }
- if ( !found ) {
- /*
- * Expected headers not found in server response.
- * Break the processing loop.
- */
- break;
- }
- }
- }
-
- if ( !found ) {
- StringBuilder actualBuffer = new StringBuilder( 128 );
- if ( resultOut != null ) {
- expectedString = "<expectedHeaderNotFound>" + currentHeaderField + ": " + currentHeaderValue + "</expectedHeader>\n";
- }
- if ( !headers.isEmpty() ) {
- Iterator iter = headers.keySet().iterator();
- while ( iter.hasNext() ) {
- String headerName = (String) iter.next();
- ArrayList vals = (ArrayList) headers.get( headerName );
- String[] val = (String[]) vals.toArray( new String[ vals.size() ] );
- for ( int i = 0; i < val.length; i++ ) {
- if ( resultOut != null ) {
- actualBuffer.append( "<actualHeader>" + headerName + ": " + val[ i ] + "</actualHeader>\n" );
- }
- }
- }
- if ( resultOut != null ) {
- resultOut.append( expectedString );
- resultOut.append( actualBuffer.toString() );
- }
- }
- return false;
- }
- }
-
- /*
- * Check to see if we're looking for unexpected headers.
- * If we are, compare the values in the unexectedHeaders
- * ArrayList against the headers from the server response.
- * if the unexpected header is found, then return false.
- */
-
- if ( !unexpectedHeaders.isEmpty() ) {
- boolean found = false;
- String unExpHeader = null;
- // Check if we got any unexpected headers
-
- if ( !copiedHeaders.isEmpty() ) {
- Iterator unexpectedIterator = unexpectedHeaders.keySet().iterator();
- while ( unexpectedIterator.hasNext() ) {
- found = false;
- String unexpectedFieldName = (String) unexpectedIterator.next();
- ArrayList unexpectedValues = (ArrayList) unexpectedHeaders.get( unexpectedFieldName );
- Iterator headersIterator = copiedHeaders.keySet().iterator();
-
- while ( headersIterator.hasNext() ) {
- String headerFieldName = (String) headersIterator.next();
- ArrayList headerValues = (ArrayList) copiedHeaders.get( headerFieldName );
-
- // compare field names and values in an HTTP 1.x compliant fashion
- if ( ( headerFieldName.equalsIgnoreCase( unexpectedFieldName ) ) ) {
- int hSize = headerValues.size();
- int eSize = unexpectedValues.size();
- int numberFound = 0;
- for ( int i = 0; i < eSize; i++ ) {
- if ( headerValues.contains( unexpectedValues.get( i ) ) ) {
- numberFound++;
- if (headerValues.indexOf(headerFieldName) >= 0) {
- headerValues.remove( headerValues.indexOf( headerFieldName ) );
- }
- }
- }
- if ( numberFound == eSize ) {
- found = true;
- }
- }
- }
- if ( !found ) {
- /*
- * Expected headers not found in server response.
- * Break the processing loop.
- */
- break;
- }
- }
- }
-
- if ( found ) {
- resultOut.append( "\n Unexpected header received from server: " + unExpHeader );
- return false;
- }
- }
-
-
-
- if ( responseMatch != null ) {
- // check if we got the string we wanted
- if ( expectResponseBody && responseBody == null ) {
- resultOut.append( "\n ERROR: got no response, expecting " + responseMatch );
- return false;
- }
- String responseBodyString = new String( responseBody );
- if ( responseBodyString.indexOf( responseMatch ) < 0 ) {
- resultOut.append( "\n ERROR: expecting match on " + responseMatch );
- resultOut.append( "\n Received: \n" + responseBodyString );
- }
- }
-
- if ( !expectResponseBody && responseBody != null ) {
- resultOut.append("Received a response body from the server where none was expected" );
- return false;
- }
-
- // compare the body
- if ( goldenFile == null )
- return true;
-
- // Get the expected result from the "golden" file.
- byte[] expResult = getExpectedResult();
- String expResultS = (expResult == null) ? "" : new String(expResult);
- // Compare the results and set the status
- boolean cmp = true;
-
- if ( exactMatch ) {
- cmp = compare( responseBody, expResult );
- } else {
- cmp = compareWeak( responseBody, expResult );
- }
-
- if ( cmp != testCondition ) {
-
- if ( resultOut != null ) {
- expectedString = "<expectedBody>" + new String(expResult) + "</expectedBody>\n";
- actualString = "<actualBody>" +
- (responseBody != null ? new String(responseBody) : "null" ) +
- "</actualBody>\n";
- resultOut.append( expectedString );
- resultOut.append( actualString );
- }
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Replaces any |client.ip| and |client.host| parameter marks
- * with the host and IP values of the host upon which Watchdog
- * is running.
- *
- * @param request An HTTP request.
- */
- String replaceMarkers( String req, Socket socket ) {
-
- final String CLIENT_IP = "client.ip";
- final String CLIENT_HOME = "client.host";
-
- if (localIP == null || localHost == null) {
- InetAddress addr = socket.getLocalAddress();
- localHost = addr.getHostName();
- localIP = addr.getHostAddress();
- }
-
- if (req.indexOf('|') > -1) {
- StringTokenizer tok = new StringTokenizer( request, "|" );
- StringBuilder sb = new StringBuilder( 50 );
-
- while ( tok.hasMoreElements() ) {
- String token = tok.nextToken();
- if ( token.equals( CLIENT_IP ) ) {
- sb.append( localIP );
- } else if ( token.equals( CLIENT_HOME ) ) {
- sb.append( localHost );
- } else {
- sb.append( token );
- }
- }
- return sb.toString();
- } else {
- return req;
- }
- }
-
-
-
- /**
- * <code>getExpectedResult</code> returns a byte array
- * containing the content of the configured goldenfile
- *
- * @return goldenfile as a byte[]
- * @exception IOException if an error occurs
- */
- private byte[] getExpectedResult()
- throws IOException {
- byte[] expResult = { 'N','O',' ',
- 'G','O','L','D','E','N','F','I','L','E',' ',
- 'F','O','U','N','D' };
-
- try {
- InputStream in = new BufferedInputStream(
- new FileInputStream( goldenFile ) );
- return readBody ( in );
- } catch ( Exception ex ) {
- System.out.println( "Golden file not found: " + goldenFile );
- return expResult;
- }
- }
-
- /**
- * <code>compare</code> compares the two byte arrays passed
- * in to verify that the lengths of the arrays are equal, and
- * that the content of the two arrays, byte for byte are equal.
- *
- * @param fromServer a <code>byte[]</code> value
- * @param fromGoldenFile a <code>byte[]</code> value
- * @return <code>boolean</code> true if equal, otherwise false
- */
- private boolean compare( byte[] fromServer, byte[] fromGoldenFile ) {
- if ( fromServer == null || fromGoldenFile == null ) {
- return false;
- }
-
- /*
- * Check to see that the respose and golden file lengths
- * are equal. If they are not, dump the hex and don't
- * bother comparing the bytes. If they are equal,
- * iterate through the byte arrays and compare each byte.
- * If the bytes don't match, dump the hex representation
- * of the server response and the goldenfile and return
- * false.
- */
- if ( fromServer.length != fromGoldenFile.length ) {
- StringBuilder sb = new StringBuilder( 50 );
- sb.append( " Response and golden files lengths do not match!\n" );
- sb.append( " Server response length: " );
- sb.append( fromServer.length );
- sb.append( "\n Goldenfile length: " );
- sb.append( fromGoldenFile.length );
- resultOut.append( sb.toString() );
- sb = null;
- // dump the hex representation of the byte arrays
- dumpHex( fromServer, fromGoldenFile );
-
- return false;
- } else {
-
- int i = 0;
- int j = 0;
-
- while ( ( i < fromServer.length ) && ( j < fromGoldenFile.length ) ) {
- if ( fromServer[ i ] != fromGoldenFile[ j ] ) {
- resultOut.append( "\n Error at position " + ( i + 1 ) );
- // dump the hex representation of the byte arrays
- dumpHex( fromServer, fromGoldenFile );
-
- return false;
- }
-
- i++;
- j++;
- }
- }
-
- return true;
- }
-
- /**
- * <code>compareWeak</code> creates new Strings from the passed arrays
- * and then uses a StringTokenizer to compare non-whitespace tokens.
- *
- * @param fromServer a <code>byte[]</code> value
- * @param fromGoldenFile a <code>byte[]</code> value
- * @return a <code>boolean</code> value
- */
- private boolean compareWeak( byte[] fromServer, byte[] fromGoldenFile ) {
- if ( fromServer == null || fromGoldenFile == null ) {
- return false;
- }
-
- boolean status = true;
-
- String server = new String( fromServer );
- String golden = new String( fromGoldenFile );
-
- StringTokenizer st1 = new StringTokenizer( server );
-
- StringTokenizer st2 = new StringTokenizer( golden );
-
- while ( st1.hasMoreTokens() && st2.hasMoreTokens() ) {
- String tok1 = st1.nextToken();
- String tok2 = st2.nextToken();
-
- if ( !tok1.equals( tok2 ) ) {
- resultOut.append( "\t FAIL*** : Rtok1 = " + tok1
- + ", Etok2 = " + tok2 );
- status = false;
- }
- }
-
- if ( st1.hasMoreTokens() || st2.hasMoreTokens() ) {
- status = false;
- }
-
- if ( !status ) {
- StringBuilder sb = new StringBuilder( 255 );
- sb.append( "ERROR: Server's response and configured goldenfile do not match!\n" );
- sb.append( "Response received from server:\n" );
- sb.append( "---------------------------------------------------------\n" );
- sb.append( server );
- sb.append( "\nContent of Goldenfile:\n" );
- sb.append( "---------------------------------------------------------\n" );
- sb.append( golden );
- sb.append( "\n" );
- resultOut.append( sb.toString() );
- }
- return status;
- }
-
- /**
- * <code>readBody</code> reads the body of the response
- * from the InputStream.
- *
- * @param input an <code>InputStream</code>
- * @return a <code>byte[]</code> representation of the response
- */
- private byte[] readBody( InputStream input ) {
- StringBuilder sb = new StringBuilder( 255 );
- while ( true ) {
- try {
- int ch = input.read();
-
- if ( ch < 0 ) {
- if ( sb.length() == 0 ) {
- return ( null );
- } else {
- break;
- }
- }
- sb.append( ( char ) ch );
-
- } catch ( IOException ex ) {
- return null;
- }
- }
- return sb.toString().getBytes();
- }
-
- /**
- * <code>setHeaderDetails</code> Wrapper method for parseHeader.
- * Allows easy addition of headers to the specified
- * HashMap
- *
- * @param line a <code>String</code> value
- * @param headerMap a <code>HashMap</code> value
- * @param isRequest a <code>boolean</code> indicating if the passed Header
- * HashMap is for request headers
- */
- void setHeaderDetails( String line, HashMap headerHash, boolean isRequest ) {
- StringTokenizer stk = new StringTokenizer( line, "##" );
-
- while ( stk.hasMoreElements( ) ) {
- String presentHeader = stk.nextToken();
- parseHeader( presentHeader, headerHash, isRequest );
- }
- }
-
- /**
- * <code>parseHeader</code> parses input headers in format of "key:value"
- * The parsed header field-name will be used as a key in the passed
- * HashMap object, and the values found will be stored in an ArrayList
- * associated with the field-name key.
- *
- * @param line String representation of an HTTP header line.
- * @param headers a<code>HashMap</code> to store key/value header objects.
- * @param isRequest set to true if the headers being processed are
- * requestHeaders.
- */
- void parseHeader( String line, HashMap headerMap, boolean isRequest ) {
- // Parse the header name and value
- int colon = line.indexOf( ":" );
-
- if ( colon < 0 ) {
- resultOut.append( "\n ERROR: Header is in incorrect format: " + line );
- return ;
- }
-
- String name = line.substring( 0, colon ).trim();
- String value = line.substring( colon + 1 ).trim();
-
- if ( ( cookieVector != null ) && ( name.equalsIgnoreCase( "Set-Cookie" ) ) ) {
- cookieVector.addElement( value );
- /*
- if ( ( value.indexOf("JSESSIONID") > -1 ) || (value.indexOf("jsessionid") > -1 ) )
- {
- String sessionId= value.substring( value.indexOf("=")+1);
- if ( testSession != null )
- {
- sessionHash.put( testSession, sessionId );
- }
- System.out.println("Got Session-ID : " + sessionId );
- }
- */
- }
-
- // System.out.println("HEADER: " +name + " " + value);
-
- ArrayList values = (ArrayList) headerMap.get( name );
- if ( values == null ) {
- values = new ArrayList();
- }
- // HACK
- if ( value.indexOf( ',' ) > -1 && !isRequest && !name.equalsIgnoreCase( "Date" ) ) {
- StringTokenizer st = new StringTokenizer( value, "," );
- while ( st.hasMoreElements() ) {
- values.add( st.nextToken() );
- }
- } else {
- values.add( value );
- }
-
- headerMap.put( name, values );
- }
-
- /**
- * <code>dumpHex</code> helper method to dump formatted
- * hex output of the server response and the goldenfile.
- *
- * @param serverResponse a <code>byte[]</code> value
- * @param goldenFile a <code>byte[]</code> value
- */
- private void dumpHex( byte[] serverResponse, byte[] goldenFile ) {
- StringBuilder outBuf = new StringBuilder( ( serverResponse.length + goldenFile.length ) * 2 );
-
- String fromServerString = HexDump.getHexDump( serverResponse, 0, serverResponse.length, true );
- String fromGoldenFileString = HexDump.getHexDump( goldenFile, 0, goldenFile.length, true );
-
- outBuf.append( " Hex dump of server response and goldenfile below.\n\n### RESPONSE FROM SERVER ###\n" );
- outBuf.append( "----------------------------\n" );
- outBuf.append( fromServerString );
- outBuf.append( "\n\n### GOLDEN FILE ###\n" );
- outBuf.append( "-------------------\n" );
- outBuf.append( fromGoldenFileString );
- outBuf.append( "\n\n### END OF DUMP ###\n" );
-
- resultOut.append( outBuf.toString() );
-
- }
-
- /**
- * <code>cloneHeaders</code> returns a "cloned"
- * HashMap of the map passed in.
- *
- * @param map a <code>HashMap</code> value
- * @return a <code>HashMap</code> value
- */
- private HashMap cloneHeaders( HashMap map ) {
- HashMap dupMap = new HashMap();
- Iterator iter = map.keySet().iterator();
-
- while ( iter.hasNext() ) {
- String key = new String( (String) iter.next() );
- ArrayList origValues = (ArrayList) map.get( key );
- ArrayList dupValues = new ArrayList();
-
- String[] dupVal = (String[]) origValues.toArray( new String[ origValues.size() ] );
- for ( int i = 0; i < dupVal.length; i++ ) {
- dupValues.add( new String( dupVal[ i ] ) );
- }
-
- dupMap.put( key, dupValues );
- }
- return dupMap;
- }
-
-}
*/
package org.apache.tomcat.test.watchdog;
+import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import junit.framework.TestResult;
import junit.framework.TestSuite;
-import org.apache.tomcat.util.DomUtil;
+import org.apache.tomcat.servlets.config.deploy.DomUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class WatchdogClient {
-
- protected String base = "../watchdog";
protected String goldenDir;
protected String testMatch;
Properties props = new Properties();
protected void beforeSuite() {
-
}
protected void afterSuite(TestResult res) {
-
+ }
+
+ public Test getSuite() {
+ return getSuite(8080);
}
/**
* @param testMatch Prefix of tests to be run
* @return
*/
- public Test getSuite() {
+ public Test getSuite(int port) {
TestSuite tests = new WatchdogTests();
tests.setName(this.getClass().getSimpleName());
- props.setProperty("port", "8080");
+ props.setProperty("port", Integer.toString(port));
props.setProperty("host", "localhost");
props.setProperty("wgdir",
goldenDir);
}
}
testName = testName + ";" + this.getClass().getName();
- WatchdogTest test = new WatchdogTest(watchE, props, testName);
+ WatchdogTestCase test = new WatchdogTestCase(watchE, props, testName);
tests.addTest(test);
}
-
- // if (targetSuite.countTestCases() > 0) {
- // tests.addTest(targetSuite);
- // }
}
} catch (IOException e) {
- e.printStackTrace();
+ e.printStackTrace();
} catch (SAXException e) {
- // TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
- // TODO Auto-generated catch block
e.printStackTrace();
}
return tests;
// --------- Inner classes -------------
+ protected String getWatchdogdir() {
+ String path = System.getProperty("watchdog.home");
+ if (path != null) {
+ return path;
+ }
+ path = "..";
+ for (int i = 0; i < 10; i++) {
+ File f = new File(path + "/watchdog");
+ if (f.exists()) {
+ return f.getAbsolutePath();
+ }
+ path = path + "/..";
+ }
+ return null;
+ }
+
public class WatchdogTests extends TestSuite {
public void run(TestResult res) {
beforeSuite();
afterSuite(res);
}
}
-
+
}
static int debug = 0;
- public static void dispatch(GTest client) throws Exception {
+ public static void dispatch(WatchdogTestImpl client) throws Exception {
HashMap requestHeaders = client.requestHeaders;
String host = client.host;
int port = client.port;
String request = client.request;
// XXX headers are ignored
- Socket socket = new Socket( host, port );
+ Socket socket;
+ try {
+ socket = new Socket( host, port );
+ } catch (IOException ex) {
+ System.out.println( " Socket Exception: " + ex );
+ return;
+ }
+ //socket.setSoTimeout(10000);
//socket obtained, rebuild the request.
rebuildRequest(client, client.request, socket);
OutputStream out = new BufferedOutputStream(
socket.getOutputStream() );
- StringBuilder reqbuf = new StringBuilder( 128 );
+ StringBuffer reqbuf = new StringBuffer( 128 );
// set the Host header
client.setHeaderDetails( "Host:" + host + ":" + port, requestHeaders, true );
Iterator iter = requestHeaders.keySet().iterator();
while ( iter.hasNext() ) {
- StringBuilder tmpBuf = new StringBuilder(32);
+ StringBuffer tmpBuf = new StringBuffer(32);
String headerKey = ( String ) iter.next();
ArrayList values = (ArrayList) requestHeaders.get( headerKey );
String[] value = (String[]) values.toArray( new String[ values.size() ] );
} catch ( SocketException ex ) {
System.out.println( " Socket Exception: " + ex );
- ex.printStackTrace();
} finally {
if ( debug > 0 ) {
System.out.println( " closing socket" );
* @return a <code>byte[]</code> representation of the response
*/
private static byte[] readBody( InputStream input ) {
- StringBuilder sb = new StringBuilder( 255 );
+ StringBuffer sb = new StringBuffer( 255 );
while ( true ) {
try {
int ch = input.read();
*/
private static String read( InputStream input ) throws IOException {
// Read the next line from the input stream
- StringBuilder sb = new StringBuilder();
+ StringBuffer sb = new StringBuffer();
while ( true ) {
try {
*
* @exception IOException if an input/output error occurs
*/
- private static HashMap parseHeaders( GTest client, InputStream is ) throws IOException {
+ private static HashMap parseHeaders( WatchdogTestImpl client, InputStream is ) throws IOException {
HashMap headers = new HashMap();
client.cookieVector = new Vector();
*
* @exception Exception if an error occurs
*/
- private static void rebuildRequest(GTest client, String req, Socket socket) throws Exception {
+ private static void rebuildRequest(WatchdogTestImpl client, String req, Socket socket) throws Exception {
client.request = client.replaceMarkers(req, socket );
String addressString = client.request.substring( client.request.indexOf( "/" ), client.request.indexOf( "HTTP" ) ).trim();
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tomcat.test.watchdog;
-
-import java.util.Properties;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-
-import org.apache.tomcat.util.IntrospectionUtils;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-public class WatchdogTest extends TestCase {
- String testName;
-
- Element watchE;
-
- private Properties props;
-
- private WatchdogTest delegate;
- private WatchdogClient wc;
-
- public WatchdogTest(String s) throws Throwable {
- String[] comp = s.split(";");
- Class c = Class.forName(comp[1]);
- wc = (WatchdogClient) c.newInstance();
- TestSuite suite = (TestSuite) wc.getSuite();
- // need to encode the base, file, etc in the test name
-
- System.err.println(s);
-
- for (int i = 0; i < suite.testCount(); i++) {
- WatchdogTest t = (WatchdogTest) suite.testAt(i);
- if (s.equals(t.getName())) {
- delegate = t;
- return;
- }
- }
- }
-
- public WatchdogTest(Element watchE, Properties props, String testName) {
- this.testName = testName;
- this.watchE = watchE;
- this.props = props;
- }
-
- public int countTestCases() {
- return 1;
- }
-
- public String getName() {
- return testName;
- }
-
- public void run(TestResult res) {
- if (delegate != null) {
- // Single method run
- wc.beforeSuite();
- delegate.run(res);
- wc.afterSuite(res);
- return;
- }
- GTest test = new GTest();
- NamedNodeMap attrs = watchE.getAttributes();
-
- for (int i = 0; i < attrs.getLength(); i++) {
- Node n = attrs.item(i);
- String name = n.getNodeName();
- String value = n.getNodeValue();
- value = IntrospectionUtils.replaceProperties(value, props, null);
- try {
- IntrospectionUtils.setProperty(test, name, value);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- try {
- res.startTest(this);
- IntrospectionUtils.execute(test, "execute");
- } catch (Throwable e) {
- res.addError(this, e);
- // res.stop();
- }
-
- if (test.passCount == 1) {
- res.endTest(this);
- return;
- } else {
- if (test.lastError == null) {
- res.addFailure(this, new AssertionFailedError(test.request
- + " " + test.description + "\n" + test.resultOut));
- } else {
- res.addError(this, test.lastError);
- }
- }
- res.endTest(this);
- }
-
-}
--- /dev/null
+/*
+ */
+package org.apache.tomcat.test.watchdog;
+
+import java.util.Properties;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import org.apache.tomcat.integration.DynamicObject;
+import org.apache.tomcat.integration.simple.AntProperties;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class WatchdogTestCase implements Test {
+ String testName;
+
+ Element watchE;
+
+ private Properties props;
+
+ private WatchdogTestCase delegate;
+ private WatchdogClient wc;
+
+ public WatchdogTestCase(String s) throws Throwable {
+ String[] comp = s.split(";");
+ if (comp.length < 2) {
+ return;
+ }
+ Class c = Class.forName(comp[1]);
+ wc = (WatchdogClient) c.newInstance();
+ TestSuite suite = (TestSuite) wc.getSuite();
+ // need to encode the base, file, etc in the test name
+
+ System.err.println(s);
+
+ for (int i = 0; i < suite.testCount(); i++) {
+ WatchdogTestCase t = (WatchdogTestCase) suite.testAt(i);
+ if (s.equals(t.getName())) {
+ delegate = t;
+ return;
+ }
+ }
+ }
+
+ public WatchdogTestCase(Element watchE, Properties props, String testName) {
+ this.testName = testName;
+ this.watchE = watchE;
+ this.props = props;
+ }
+
+ public int countTestCases() {
+ return 1;
+ }
+
+ public String getName() {
+ return testName;
+ }
+
+ public void testDummy() {
+ }
+
+ public void run(TestResult res) {
+ if (delegate != null) {
+ // Single method run
+ wc.beforeSuite();
+ delegate.run(res);
+ wc.afterSuite(res);
+ return;
+ }
+ if (watchE == null) {
+ res.endTest(this);
+ return;
+ }
+ WatchdogTestImpl test = new WatchdogTestImpl();
+ NamedNodeMap attrs = watchE.getAttributes();
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Node n = attrs.item(i);
+ String name = n.getNodeName();
+ String value = n.getNodeValue();
+ value = AntProperties.replaceProperties(value, props, null);
+ try {
+ new DynamicObject(test.getClass()).setProperty(test,
+ name, value);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ res.startTest(this);
+ new DynamicObject(test.getClass()).invoke(test, "execute");
+ } catch (Throwable e) {
+ res.addError(this, e);
+ // res.stop();
+ }
+
+ if (test.passCount == 1) {
+ res.endTest(this);
+ return;
+ } else {
+ if (test.lastError == null) {
+ res.addFailure(this, new AssertionFailedError(test.request
+ + " " + test.description + "\n" + test.resultOut));
+ } else {
+ res.addError(this, test.lastError);
+ }
+ }
+ res.endTest(this);
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @Author Costin, Ramesh.Mandava
+ */
+
+package org.apache.tomcat.test.watchdog;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tomcat.lite.io.Hex;
+
+// derived from Jsp
+
+public class WatchdogTestImpl {
+
+ int failureCount = 0;
+
+ int passCount = 0;
+
+ Throwable lastError;
+
+ boolean hasFailed = false;
+
+ String prefix = "http";
+
+ String host = "localhost";
+
+ String localHost = null;
+
+ String localIP = null;
+
+ int port = 8080;
+
+ int debug = 0;
+
+ String description = "No description";
+
+ String request;
+
+ HashMap requestHeaders = new HashMap();
+
+ String content;
+
+ // true if task is nested
+ private boolean nested = false;
+
+ // Expected response
+ boolean magnitude = true;
+
+ boolean exactMatch = false;
+
+ // expect a response body
+ boolean expectResponseBody = true;
+
+ // Match the body against a golden file
+ String goldenFile;
+
+ // Match the body against a string
+ String responseMatch;
+
+ // the response should include the following headers
+ HashMap expectHeaders = new HashMap();
+
+ // Headers that should not be found in response
+ HashMap unexpectedHeaders = new HashMap();
+
+ // Match request line
+ String returnCode = "";
+
+ String returnCodeMsg = "";
+
+ // Actual response
+ String responseLine;
+
+ byte[] responseBody;
+
+ HashMap headers;
+
+ // For Report generation
+ StringBuffer resultOut = new StringBuffer();
+
+ boolean firstTask = false;
+
+ boolean lastTask = false;
+
+ String expectedString;
+
+ String actualString;
+
+ String testName;
+
+ String assertion;
+
+ String testStrategy;
+
+ // For Session Tracking
+ static Hashtable sessionHash;
+
+ static Hashtable cookieHash;
+
+ String testSession;
+
+ Vector cookieVector;
+
+ URL requestURL;
+
+ CookieController cookieController;
+
+ /**
+ * Creates a new <code>GTest</code> instance.
+ *
+ */
+ public WatchdogTestImpl() {
+ }
+
+ /**
+ * <code>setTestSession</code> adds a CookieController for the value of
+ * sessionName
+ *
+ * @param sessionName
+ * a <code>String</code> value
+ */
+ public void setTestSession(String sessionName) {
+ testSession = sessionName;
+
+ if (sessionHash == null) {
+ sessionHash = new Hashtable();
+ } else if (sessionHash.get(sessionName) == null) {
+ sessionHash.put(sessionName, new CookieController());
+ }
+ }
+
+ /**
+ * <code>setTestName</code> sets the current test name.
+ *
+ * @param tn
+ * current testname.
+ */
+ public void setTestName(String tn) {
+ testName = tn;
+ }
+
+ /**
+ * <code>setAssertion</code> sets the assertion text for the current test.
+ *
+ * @param assertion
+ * assertion text
+ */
+ public void setAssertion(String assertion) {
+ this.assertion = assertion;
+ }
+
+ /**
+ * <code>setTestStrategy</code> sets the test strategy for the current test.
+ *
+ * @param strategy
+ * test strategy text
+ */
+ public void setTestStrategy(String strategy) {
+ testStrategy = strategy;
+ }
+
+ /**
+ * <code>getTestName</code> returns the current test name.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getTestName() {
+ return testName;
+ }
+
+ /**
+ * <code>getAssertion</code> returns the current assertion text.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getAssertion() {
+ return assertion;
+ }
+
+ /**
+ * <code>getTestStrategy</code> returns the current test strategy test.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getTestStrategy() {
+ return testStrategy;
+ }
+
+ /**
+ * <code>setFirstTask</code> denotes that current task being executed is the
+ * first task within the list.
+ *
+ * @param a
+ * <code>boolean</code> value
+ */
+ public void setFirstTask(boolean val) {
+ firstTask = val;
+ }
+
+ /**
+ * <code>setLastTask</code> denotes that the current task being executed is
+ * the last task within the list.
+ *
+ * @param a
+ * <code>boolean</code> value
+ */
+ public void setLastTask(boolean val) {
+ lastTask = val;
+ }
+
+ /**
+ * <code>setPrefix</code> sets the protocol prefix. Defaults to "http"
+ *
+ * @param prefix
+ * Either http or https
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * <code>setHost</code> sets hostname where the target server is running.
+ * Defaults to "localhost"
+ *
+ * @param h
+ * a <code>String</code> value
+ */
+ public void setHost(String h) {
+ this.host = h;
+ }
+
+ /**
+ * <code>setPort</code> sets the port that the target server is listening
+ * on. Defaults to "8080"
+ *
+ * @param portS
+ * a <code>String</code> value
+ */
+ public void setPort(String portS) {
+ this.port = Integer.valueOf(portS).intValue();
+ }
+
+ /**
+ * <code>setExactMatch</code> determines if a byte-by-byte comparsion is
+ * made of the server's response and the test's goldenFile, or if a token
+ * comparison is made. By default, only a token comparison is made
+ * ("false").
+ *
+ * @param exact
+ * a <code>String</code> value
+ */
+ public void setExactMatch(String exact) {
+ exactMatch = Boolean.valueOf(exact).booleanValue();
+ }
+
+ /**
+ * <code>setContent</code> String value upon which the request header
+ * Content-Length is based upon.
+ *
+ * @param s
+ * a <code>String</code> value
+ */
+ public void setContent(String s) {
+ this.content = s;
+ }
+
+ /**
+ * <code>setDebug</code> enables debug output. By default, this is disabled
+ * ( value of "0" ).
+ *
+ * @param debugS
+ * a <code>String</code> value
+ */
+ public void setDebug(String debugS) {
+ debug = Integer.valueOf(debugS).intValue();
+ }
+
+ /**
+ * <code>setMagnitude</code> Expected return value of the test execution.
+ * Defaults to "true"
+ *
+ * @param magnitudeS
+ * a <code>String</code> value
+ */
+ public void setMagnitude(String magnitudeS) {
+ magnitude = Boolean.valueOf(magnitudeS).booleanValue();
+ }
+
+ /**
+ * <code>setGoldenFile</code> Sets the goldenfile that will be used to
+ * validate the server's response.
+ *
+ * @param s
+ * fully qualified path and filename
+ */
+ public void setGoldenFile(String s) {
+ this.goldenFile = s;
+ }
+
+ /**
+ * <code>setExpectResponseBody</code> sets a flag to indicate if a response
+ * body is expected from the server or not
+ *
+ * @param b
+ * a <code>boolean</code> value
+ */
+ public void setExpectResponseBody(boolean b) {
+ this.expectResponseBody = b;
+ }
+
+ /**
+ * <code>setExpectHeaders</code> Configures GTest to look for the header
+ * passed in the server's response.
+ *
+ * @param s
+ * a <code>String</code> value in the format of
+ * <header-field>:<header-value>
+ */
+ public void setExpectHeaders(String s) {
+ this.expectHeaders = new HashMap();
+ StringTokenizer tok = new StringTokenizer(s, "|");
+ while (tok.hasMoreElements()) {
+ String header = (String) tok.nextElement();
+ setHeaderDetails(header, expectHeaders, false);
+ }
+ }
+
+ /**
+ * <code>setUnexpectedHeaders</code> Configures GTest to look for the header
+ * passed to validate that it doesn't exist in the server's response.
+ *
+ * @param s
+ * a <code>String</code> value in the format of
+ * <header-field>:<header-value>
+ */
+ public void setUnexpectedHeaders(String s) {
+ this.unexpectedHeaders = new HashMap();
+ setHeaderDetails(s, unexpectedHeaders, false);
+ }
+
+ public void setNested(String s) {
+ nested = Boolean.valueOf(s).booleanValue();
+ }
+
+ /**
+ * <code>setResponseMatch</code> Match the passed value in the server's
+ * response.
+ *
+ * @param s
+ * a <code>String</code> value
+ */
+ public void setResponseMatch(String s) {
+ this.responseMatch = s;
+ }
+
+ /**
+ * <code>setRequest</code> Sets the HTTP/HTTPS request to be sent to the
+ * target server Ex. GET /servlet_path/val HTTP/1.0
+ *
+ * @param s
+ * a <code>String</code> value in the form of METHOD PATH
+ * HTTP_VERSION
+ */
+ public void setRequest(String s) {
+ this.request = s;
+ }
+
+ /**
+ * <code>setReturnCode</code> Sets the expected return code from the
+ * server's response.
+ *
+ * @param code
+ * a valid HTTP response status code
+ */
+ public void setReturnCode(String code) {
+ this.returnCode = code;
+ }
+
+ /**
+ * Describe <code>setReturnCodeMsg</code> Sets the expected return message
+ * to be found in the server's response.
+ *
+ * @param code
+ * a valid HTTP resonse status code
+ * @param message
+ * a <code>String</code> value
+ */
+ public void setReturnCodeMsg(String message) {
+ this.returnCodeMsg = message;
+ }
+
+ /**
+ * <code>setRequestHeaders</code> Configures the request headers GTest
+ * should send to the target server.
+ *
+ * @param s
+ * a <code>String</code> value in for format of
+ * <field-name>:<field-value>
+ */
+ public void setRequestHeaders(String s) {
+ requestHeaders = new HashMap();
+ StringTokenizer tok = new StringTokenizer(s, "|");
+ while (tok.hasMoreElements()) {
+ String header = (String) tok.nextElement();
+ setHeaderDetails(header, requestHeaders, true);
+ }
+ }
+
+ // Inner tests are not used currently, can be reworked
+
+ // /**
+ // * Add a Task to this container
+ // *
+ // * @param Task to add
+ // */
+ // public void addTask(Task task) {
+ // children.add(task);
+ // }
+
+ /**
+ * <code>execute</code> Executes the test.
+ *
+ * @exception BuildException
+ * if an error occurs
+ */
+ public void execute() {
+
+ try {
+
+ if (resultOut != null && !nested) {
+ resultOut.append("\ntestName: " + testName);
+ resultOut.append("\nreq: " + request);
+ resultOut.append("\nassertion: " + assertion);
+ resultOut.append("\ntestStrategy: " + testStrategy);
+ }
+
+ WatchdogHttpClient.dispatch(this);
+
+ hasFailed = !checkResponse(magnitude);
+
+ // if ( !children.isEmpty() ) {
+ // Iterator iter = children.iterator();
+ // while (iter.hasNext()) {
+ // Task task = (Task) iter.next();
+ // task.perform();
+ // }
+ // }
+
+ if (!hasFailed && !nested) {
+ passCount++;
+ if (resultOut != null) {
+ resultOut.append("<result>PASS</result>\n");
+ }
+// System.out.println(" PASSED " + testName + " ("
+// + request + ")");
+ } else if (hasFailed && !nested) {
+ failureCount++;
+ if (resultOut != null) {
+ resultOut.append("<result>FAIL</result>\n");
+ }
+ System.out.println(" FAILED " + testName + "\n ("
+ + request + ")\n" + resultOut.toString());
+ }
+
+ } catch (Exception ex) {
+ failureCount++;
+ System.out.println(" FAIL " + description + " (" + request + ")");
+ lastError = ex;
+ ex.printStackTrace();
+ } finally {
+ if (!nested) {
+ hasFailed = false;
+ }
+ }
+ }
+
+ /**
+ * <code>checkResponse</code> Executes various response checking mechanisms
+ * against the server's response. Checks include:
+ * <ul>
+ * <li>expected headers
+ * <li>unexpected headers
+ * <li>return codes and messages in the Status-Line
+ * <li>response body comparison againt a goldenfile
+ * </ul>
+ *
+ * @param testCondition
+ * a <code>boolean</code> value
+ * @return a <code>boolean</code> value
+ * @exception Exception
+ * if an error occurs
+ */
+ private boolean checkResponse(boolean testCondition) throws Exception {
+ boolean match = false;
+
+ if (responseLine != null) {
+ // If returnCode doesn't match
+ if (responseLine.indexOf("HTTP/1.") > -1) {
+
+ if (!returnCode.equals("")) {
+ boolean resCode = (responseLine.indexOf(returnCode) > -1);
+ boolean resMsg = (responseLine.indexOf(returnCodeMsg) > -1);
+
+ if (returnCodeMsg.equals("")) {
+ match = resCode;
+ } else {
+ match = (resCode && resMsg);
+ }
+
+ if (match != testCondition) {
+
+ if (resultOut != null) {
+ String expectedStatusCode = "<expectedStatusCode>"
+ + returnCode + "</expectedReturnCode>\n";
+ String expectedReasonPhrase = "<expectedReasonPhrase>"
+ + returnCodeMsg + "</expectedReasonPhrase>";
+ actualString = "<actualStatusLine>" + responseLine
+ + "</actualStatusLine>\n";
+ resultOut.append(expectedStatusCode);
+ resultOut.append(expectedReasonPhrase);
+ resultOut.append(actualString);
+ }
+
+ return false;
+ }
+ }
+ } else {
+ resultOut.append("\n<failure>Wrong Http version: "
+ + responseLine + "</failure>");
+ return false;
+ }
+ } else {
+ resultOut.append("\n<failure>No response from server</failure>");
+ return false;
+ }
+
+ /*
+ * Check for headers the test expects to be in the server's response
+ */
+
+ // Duplicate set of response headers
+ HashMap copiedHeaders = cloneHeaders(headers);
+
+ // used for error reporting
+ String currentHeaderField = null;
+ String currentHeaderValue = null;
+
+ if (!expectHeaders.isEmpty()) {
+ boolean found = false;
+ String expHeader = null;
+
+ if (!headers.isEmpty()) {
+ Iterator expectIterator = expectHeaders.keySet().iterator();
+ while (expectIterator.hasNext()) {
+ found = false;
+ String expFieldName = (String) expectIterator.next();
+ currentHeaderField = expFieldName;
+ ArrayList expectValues = (ArrayList) expectHeaders
+ .get(expFieldName);
+ Iterator headersIterator = copiedHeaders.keySet()
+ .iterator();
+
+ while (headersIterator.hasNext()) {
+ String headerFieldName = (String) headersIterator
+ .next();
+ ArrayList headerValues = (ArrayList) copiedHeaders
+ .get(headerFieldName);
+
+ // compare field names and values in an HTTP 1.x
+ // compliant fashion
+ if ((headerFieldName.equalsIgnoreCase(expFieldName))) {
+ int hSize = headerValues.size();
+ int eSize = expectValues.size();
+
+ // number of expected headers found in server
+ // response
+ int numberFound = 0;
+
+ for (int i = 0; i < eSize; i++) {
+ currentHeaderValue = (String) expectValues
+ .get(i);
+
+ /*
+ * Handle the Content-Type header appropriately
+ * based on the the test is configured to look
+ * for.
+ */
+ if (currentHeaderField
+ .equalsIgnoreCase("content-type")) {
+ String resVal = (String) headerValues
+ .get(0);
+ if (currentHeaderValue.indexOf(';') > -1) {
+ if (currentHeaderValue.equals(resVal)) {
+ numberFound++;
+ headerValues.remove(0);
+ }
+ } else if (resVal
+ .indexOf(currentHeaderValue) > -1) {
+ numberFound++;
+ headerValues.remove(0);
+ }
+ } else if (currentHeaderField
+ .equalsIgnoreCase("location")) {
+ String resVal = (String) headerValues
+ .get(0);
+ int idx = currentHeaderValue
+ .indexOf(":80/");
+ if (idx > -1) {
+ String tempValue = currentHeaderValue
+ .substring(0, idx)
+ + currentHeaderValue
+ .substring(idx + 3);
+ if (currentHeaderValue.equals(resVal)
+ || tempValue.equals(resVal)) {
+ numberFound++;
+ headerValues.remove(0);
+ }
+ } else {
+ if (currentHeaderValue.equals(resVal)) {
+ numberFound++;
+ headerValues.remove(0);
+ }
+ }
+ } else if (headerValues
+ .contains(currentHeaderValue)) {
+ numberFound++;
+ headerValues.remove(headerValues
+ .indexOf(currentHeaderValue));
+ }
+ }
+ if (numberFound == eSize) {
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ /*
+ * Expected headers not found in server response. Break
+ * the processing loop.
+ */
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ StringBuffer actualBuffer = new StringBuffer(128);
+ if (resultOut != null) {
+ expectedString = "<expectedHeaderNotFound>"
+ + currentHeaderField + ": " + currentHeaderValue
+ + "</expectedHeader>\n";
+ }
+ if (!headers.isEmpty()) {
+ Iterator iter = headers.keySet().iterator();
+ while (iter.hasNext()) {
+ String headerName = (String) iter.next();
+ ArrayList vals = (ArrayList) headers.get(headerName);
+ String[] val = (String[]) vals.toArray(new String[vals
+ .size()]);
+ for (int i = 0; i < val.length; i++) {
+ if (resultOut != null) {
+ actualBuffer.append("<actualHeader>"
+ + headerName + ": " + val[i]
+ + "</actualHeader>\n");
+ }
+ }
+ }
+ if (resultOut != null) {
+ resultOut.append(expectedString);
+ resultOut.append(actualBuffer.toString());
+ }
+ }
+ return false;
+ }
+ }
+
+ /*
+ * Check to see if we're looking for unexpected headers. If we are,
+ * compare the values in the unexectedHeaders ArrayList against the
+ * headers from the server response. if the unexpected header is found,
+ * then return false.
+ */
+
+ if (!unexpectedHeaders.isEmpty()) {
+ boolean found = false;
+ String unExpHeader = null;
+ // Check if we got any unexpected headers
+
+ if (!copiedHeaders.isEmpty()) {
+ Iterator unexpectedIterator = unexpectedHeaders.keySet()
+ .iterator();
+ while (unexpectedIterator.hasNext()) {
+ found = false;
+ String unexpectedFieldName = (String) unexpectedIterator
+ .next();
+ ArrayList unexpectedValues = (ArrayList) unexpectedHeaders
+ .get(unexpectedFieldName);
+ Iterator headersIterator = copiedHeaders.keySet()
+ .iterator();
+
+ while (headersIterator.hasNext()) {
+ String headerFieldName = (String) headersIterator
+ .next();
+ ArrayList headerValues = (ArrayList) copiedHeaders
+ .get(headerFieldName);
+
+ // compare field names and values in an HTTP 1.x
+ // compliant fashion
+ if ((headerFieldName
+ .equalsIgnoreCase(unexpectedFieldName))) {
+ int hSize = headerValues.size();
+ int eSize = unexpectedValues.size();
+ int numberFound = 0;
+ for (int i = 0; i < eSize; i++) {
+ if (headerValues.contains(unexpectedValues
+ .get(i))) {
+ numberFound++;
+ if (headerValues.indexOf(headerFieldName) >= 0) {
+ headerValues.remove(headerValues
+ .indexOf(headerFieldName));
+ }
+ }
+ }
+ if (numberFound == eSize) {
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ /*
+ * Expected headers not found in server response. Break
+ * the processing loop.
+ */
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ resultOut.append("\n Unexpected header received from server: "
+ + unExpHeader);
+ return false;
+ }
+ }
+
+ if (responseMatch != null) {
+ // check if we got the string we wanted
+ if (expectResponseBody && responseBody == null) {
+ resultOut.append("\n ERROR: got no response, expecting "
+ + responseMatch);
+ return false;
+ }
+ String responseBodyString = new String(responseBody);
+ if (responseBodyString.indexOf(responseMatch) < 0) {
+ resultOut.append("\n ERROR: expecting match on "
+ + responseMatch);
+ resultOut.append("\n Received: \n" + responseBodyString);
+ }
+ }
+
+ if (!expectResponseBody && responseBody != null) {
+ resultOut
+ .append("Received a response body from the server where none was expected");
+ return false;
+ }
+
+ // compare the body
+ if (goldenFile == null)
+ return true;
+
+ // Get the expected result from the "golden" file.
+ byte[] expResult = getExpectedResult();
+ String expResultS = (expResult == null) ? "" : new String(expResult);
+ // Compare the results and set the status
+ boolean cmp = true;
+
+ if (exactMatch) {
+ cmp = compare(responseBody, expResult);
+ } else {
+ cmp = compareWeak(responseBody, expResult);
+ }
+
+ if (cmp != testCondition) {
+
+ if (resultOut != null) {
+ expectedString = "<expectedBody>" + new String(expResult)
+ + "</expectedBody>\n";
+ actualString = "<actualBody>"
+ + (responseBody != null ? new String(responseBody)
+ : "null") + "</actualBody>\n";
+ resultOut.append(expectedString);
+ resultOut.append(actualString);
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Replaces any |client.ip| and |client.host| parameter marks with the host
+ * and IP values of the host upon which Watchdog is running.
+ *
+ * @param request
+ * An HTTP request.
+ */
+ String replaceMarkers(String req, Socket socket) {
+
+ final String CLIENT_IP = "client.ip";
+ final String CLIENT_HOME = "client.host";
+
+ if (localIP == null || localHost == null) {
+ InetAddress addr = socket.getLocalAddress();
+ localHost = addr.getHostName();
+ localIP = addr.getHostAddress();
+ }
+
+ if (req.indexOf('|') > -1) {
+ StringTokenizer tok = new StringTokenizer(request, "|");
+ StringBuffer sb = new StringBuffer(50);
+
+ while (tok.hasMoreElements()) {
+ String token = tok.nextToken();
+ if (token.equals(CLIENT_IP)) {
+ sb.append(localIP);
+ } else if (token.equals(CLIENT_HOME)) {
+ sb.append(localHost);
+ } else {
+ sb.append(token);
+ }
+ }
+ return sb.toString();
+ } else {
+ return req;
+ }
+ }
+
+ /**
+ * <code>getExpectedResult</code> returns a byte array containing the
+ * content of the configured goldenfile
+ *
+ * @return goldenfile as a byte[]
+ * @exception IOException
+ * if an error occurs
+ */
+ private byte[] getExpectedResult() throws IOException {
+ byte[] expResult = { 'N', 'O', ' ', 'G', 'O', 'L', 'D', 'E', 'N', 'F',
+ 'I', 'L', 'E', ' ', 'F', 'O', 'U', 'N', 'D' };
+
+ try {
+ InputStream in = new BufferedInputStream(new FileInputStream(
+ goldenFile));
+ return readBody(in);
+ } catch (Exception ex) {
+ System.out.println("Golden file not found: " + goldenFile);
+ return expResult;
+ }
+ }
+
+ /**
+ * <code>compare</code> compares the two byte arrays passed in to verify
+ * that the lengths of the arrays are equal, and that the content of the two
+ * arrays, byte for byte are equal.
+ *
+ * @param fromServer
+ * a <code>byte[]</code> value
+ * @param fromGoldenFile
+ * a <code>byte[]</code> value
+ * @return <code>boolean</code> true if equal, otherwise false
+ */
+ private boolean compare(byte[] fromServer, byte[] fromGoldenFile) {
+ if (fromServer == null || fromGoldenFile == null) {
+ return false;
+ }
+
+ /*
+ * Check to see that the respose and golden file lengths are equal. If
+ * they are not, dump the hex and don't bother comparing the bytes. If
+ * they are equal, iterate through the byte arrays and compare each
+ * byte. If the bytes don't match, dump the hex representation of the
+ * server response and the goldenfile and return false.
+ */
+ if (fromServer.length != fromGoldenFile.length) {
+ StringBuffer sb = new StringBuffer(50);
+ sb.append(" Response and golden files lengths do not match!\n");
+ sb.append(" Server response length: ");
+ sb.append(fromServer.length);
+ sb.append("\n Goldenfile length: ");
+ sb.append(fromGoldenFile.length);
+ resultOut.append(sb.toString());
+ sb = null;
+ // dump the hex representation of the byte arrays
+ dumpHex(fromServer, fromGoldenFile);
+
+ return false;
+ } else {
+
+ int i = 0;
+ int j = 0;
+
+ while ((i < fromServer.length) && (j < fromGoldenFile.length)) {
+ if (fromServer[i] != fromGoldenFile[j]) {
+ resultOut.append("\n Error at position " + (i + 1));
+ // dump the hex representation of the byte arrays
+ dumpHex(fromServer, fromGoldenFile);
+
+ return false;
+ }
+
+ i++;
+ j++;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * <code>compareWeak</code> creates new Strings from the passed arrays and
+ * then uses a StringTokenizer to compare non-whitespace tokens.
+ *
+ * @param fromServer
+ * a <code>byte[]</code> value
+ * @param fromGoldenFile
+ * a <code>byte[]</code> value
+ * @return a <code>boolean</code> value
+ */
+ private boolean compareWeak(byte[] fromServer, byte[] fromGoldenFile) {
+ if (fromServer == null || fromGoldenFile == null) {
+ return false;
+ }
+
+ boolean status = true;
+
+ String server = new String(fromServer);
+ String golden = new String(fromGoldenFile);
+
+ StringTokenizer st1 = new StringTokenizer(server);
+
+ StringTokenizer st2 = new StringTokenizer(golden);
+
+ while (st1.hasMoreTokens() && st2.hasMoreTokens()) {
+ String tok1 = st1.nextToken();
+ String tok2 = st2.nextToken();
+
+ if (!tok1.equals(tok2)) {
+ resultOut.append("\t FAIL*** : Rtok1 = " + tok1 + ", Etok2 = "
+ + tok2);
+ status = false;
+ }
+ }
+
+ if (st1.hasMoreTokens() || st2.hasMoreTokens()) {
+ status = false;
+ }
+
+ if (!status) {
+ StringBuffer sb = new StringBuffer(255);
+ sb
+ .append("ERROR: Server's response and configured goldenfile do not match!\n");
+ sb.append("Response received from server:\n");
+ sb
+ .append("---------------------------------------------------------\n");
+ sb.append(server);
+ sb.append("\nContent of Goldenfile:\n");
+ sb
+ .append("---------------------------------------------------------\n");
+ sb.append(golden);
+ sb.append("\n");
+ resultOut.append(sb.toString());
+ }
+ return status;
+ }
+
+ /**
+ * <code>readBody</code> reads the body of the response from the
+ * InputStream.
+ *
+ * @param input
+ * an <code>InputStream</code>
+ * @return a <code>byte[]</code> representation of the response
+ */
+ private byte[] readBody(InputStream input) {
+ StringBuffer sb = new StringBuffer(255);
+ while (true) {
+ try {
+ int ch = input.read();
+
+ if (ch < 0) {
+ if (sb.length() == 0) {
+ return (null);
+ } else {
+ break;
+ }
+ }
+ sb.append((char) ch);
+
+ } catch (IOException ex) {
+ return null;
+ }
+ }
+ return sb.toString().getBytes();
+ }
+
+ /**
+ * <code>setHeaderDetails</code> Wrapper method for parseHeader. Allows easy
+ * addition of headers to the specified HashMap
+ *
+ * @param line
+ * a <code>String</code> value
+ * @param headerMap
+ * a <code>HashMap</code> value
+ * @param isRequest
+ * a <code>boolean</code> indicating if the passed Header HashMap
+ * is for request headers
+ */
+ void setHeaderDetails(String line, HashMap headerHash, boolean isRequest) {
+ StringTokenizer stk = new StringTokenizer(line, "##");
+
+ while (stk.hasMoreElements()) {
+ String presentHeader = stk.nextToken();
+ parseHeader(presentHeader, headerHash, isRequest);
+ }
+ }
+
+ /**
+ * <code>parseHeader</code> parses input headers in format of "key:value"
+ * The parsed header field-name will be used as a key in the passed HashMap
+ * object, and the values found will be stored in an ArrayList associated
+ * with the field-name key.
+ *
+ * @param line
+ * String representation of an HTTP header line.
+ * @param headers
+ * a<code>HashMap</code> to store key/value header objects.
+ * @param isRequest
+ * set to true if the headers being processed are requestHeaders.
+ */
+ void parseHeader(String line, HashMap headerMap, boolean isRequest) {
+ // Parse the header name and value
+ int colon = line.indexOf(":");
+
+ if (colon < 0) {
+ resultOut
+ .append("\n ERROR: Header is in incorrect format: " + line);
+ return;
+ }
+
+ String name = line.substring(0, colon).trim();
+ String value = line.substring(colon + 1).trim();
+
+ if ((cookieVector != null) && (name.equalsIgnoreCase("Set-Cookie"))) {
+ cookieVector.addElement(value);
+ /*
+ * if ( ( value.indexOf("JSESSIONID") > -1 ) ||
+ * (value.indexOf("jsessionid") > -1 ) ) { String sessionId=
+ * value.substring( value.indexOf("=")+1); if ( testSession != null
+ * ) { sessionHash.put( testSession, sessionId ); }
+ * System.out.println("Got Session-ID : " + sessionId ); }
+ */
+ }
+
+ // System.out.println("HEADER: " +name + " " + value);
+
+ ArrayList values = (ArrayList) headerMap.get(name);
+ if (values == null) {
+ values = new ArrayList();
+ }
+ // HACK
+ if (value.indexOf(',') > -1 && !isRequest
+ && !name.equalsIgnoreCase("Date")) {
+ StringTokenizer st = new StringTokenizer(value, ",");
+ while (st.hasMoreElements()) {
+ values.add(st.nextToken());
+ }
+ } else {
+ values.add(value);
+ }
+
+ headerMap.put(name, values);
+ }
+
+ /**
+ * <code>dumpHex</code> helper method to dump formatted hex output of the
+ * server response and the goldenfile.
+ *
+ * @param serverResponse
+ * a <code>byte[]</code> value
+ * @param goldenFile
+ * a <code>byte[]</code> value
+ */
+ private void dumpHex(byte[] serverResponse, byte[] goldenFile) {
+ StringBuffer outBuf = new StringBuffer(
+ (serverResponse.length + goldenFile.length) * 2);
+
+ String fromServerString = Hex.getHexDump(serverResponse, 0,
+ serverResponse.length, true);
+ String fromGoldenFileString = Hex.getHexDump(goldenFile, 0,
+ goldenFile.length, true);
+
+ outBuf
+ .append(" Hex dump of server response and goldenfile below.\n\n### RESPONSE FROM SERVER ###\n");
+ outBuf.append("----------------------------\n");
+ outBuf.append(fromServerString);
+ outBuf.append("\n\n### GOLDEN FILE ###\n");
+ outBuf.append("-------------------\n");
+ outBuf.append(fromGoldenFileString);
+ outBuf.append("\n\n### END OF DUMP ###\n");
+
+ resultOut.append(outBuf.toString());
+
+ }
+
+ /**
+ * <code>cloneHeaders</code> returns a "cloned" HashMap of the map passed
+ * in.
+ *
+ * @param map
+ * a <code>HashMap</code> value
+ * @return a <code>HashMap</code> value
+ */
+ private HashMap cloneHeaders(HashMap map) {
+ HashMap dupMap = new HashMap();
+ Iterator iter = map.keySet().iterator();
+
+ while (iter.hasNext()) {
+ String key = new String((String) iter.next());
+ ArrayList origValues = (ArrayList) map.get(key);
+ ArrayList dupValues = new ArrayList();
+
+ String[] dupVal = (String[]) origValues
+ .toArray(new String[origValues.size()]);
+ for (int i = 0; i < dupVal.length; i++) {
+ dupValues.add(new String(dupVal[i]));
+ }
+
+ dupMap.put(key, dupValues);
+ }
+ return dupMap;
+ }
+
+}