craigmcc 00/12/26 10:57:44
Modified: tester/src/bin tester.xml
tester/src/tester/org/apache/tester TestClient.java
tester/web/WEB-INF web.xml
Added: tester/src/tester/org/apache/tester GetHeaders01.java
Log:
Add a test for receiving two headers with the same name. NOTE: The
HttpURLConnection class does not handle this correctly, so the test client
now has the option to use a low-level socket connection instead of
HttpURLConnection on each test. To enable this, simply set the "protocol"
attribute to "HTTP/1.0".
Revision Changes Path
1.4 +40 -24 jakarta-tomcat-4.0/tester/src/bin/tester.xml
Index: tester.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/bin/tester.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- tester.xml 2000/12/23 04:06:46 1.3
+++ tester.xml 2000/12/26 18:57:43 1.4
@@ -4,6 +4,8 @@
<property name="catalina.home" value="../../build/tomcat-4.0"/>
<property name="host" value="localhost"/>
<property name="port" value="8080"/>
+<!-- <property name="protocol" value="HTTP/1.0"/> -->
+ <property name="protocol" value=""/> <!-- Use HttpURLConnection -->
<property name="context.path" value="/tester"/>
<taskdef name="tester" classname="org.apache.tester.TestClient"/>
@@ -16,7 +18,7 @@
<!-- ========== Basic Run State ======================================= -->
<!-- Should be able to see the home page -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/index.html"
status="200"/>
@@ -28,63 +30,63 @@
<!-- ========== Case Sensitive Request URI Matching =================== -->
<!-- Make sure that static resources are matched case sensitively -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/index.HTML"
status="404"/>
<!-- Should be able to execute the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/jsp/dates/date.jsp"
status="200"/>
<!-- Should not be able to view the source of the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/jsp/dates/date.Jsp"
status="404"/>
<!-- Should not be able to view the source of the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/jsp/dates/Date.jsp"
status="404"/>
<!-- Should not be able to view the source of the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/jsp/Dates/date.jsp"
status="404"/>
<!-- Should not be able to view the source of the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/Jsp/dates/date.jsp"
status="404"/>
<!-- Should not be able to view the source of the Date example -->
<touch file="${catalina.home}/webapps/examples/jsp/dates/date.jsp"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/Examples/jsp/dates/date.jsp"
status="404"/>
<!-- Should be able to execute the HelloWorld servlet example -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/servlet/HelloWorldExample"
status="200"/>
<!-- Should not be able to execute HelloWorld with different cases -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/servlet/helloWorldExample"
status="404"/>
<!-- Should not be able to execute HelloWorld with different cases -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/examples/Servlet/HelloWorldExample"
status="404"/>
<!-- Should not be able to execute HelloWorld with different cases -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="/Examples/servlet/HelloWorldExample"
status="404"/>
@@ -95,27 +97,27 @@
<!-- ========== Parameters and Query Strings ========================== -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/GetParameter01?foo=1"
outContent="GetParameter01 PASSED"/>
- <tester host="${host}" port="${port}" debug="0"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/WrappedGetParameter01?foo=1"
outContent="GetParameter01 PASSED"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/GetParameterMap00?BestLanguage=Java&BestJSP=Java2"
outContent="GetParameterMap00 PASSED"/>
- <tester host="${host}" port="${port}" debug="0"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/WrappedGetParameterMap00?BestLanguage=Java&BestJSP=Java2"
outContent="GetParameterMap00 PASSED"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/GetQueryString01?foo=1"
outContent="GetQueryString01 PASSED"/>
- <tester host="${host}" port="${port}" debug="0"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/WrappedGetQueryString01?foo=1"
outContent="GetQueryString01 PASSED"/>
@@ -124,11 +126,25 @@
<!-- Servlet compliance tests, until equivalent tests are included
in jakarta-watchdog-4.0. -->
- <tester host="${host}" port="${port}"
+ <!-- HttpURLConnection does not handle multiple headers for the same
+ name correctly, so use native socket connections, selected by
+ setting the protocol to "HTTP/1.0" -->
+
+ <tester host="${host}" port="${port}" protocol="HTTP/1.0"
+ request="${context.path}/GetHeaders01"
+ inHeaders="Accept-Language:en-us##Accept-Language:en-gb"
+ outContent="GetHeaders01 PASSED"/>
+
+ <tester host="${host}" port="${port}" protocol="HTTP/1.0"
+ request="${context.path}/WrappedGetHeaders01"
+ inHeaders="Accept-Language:en-us##Accept-Language:en-gb"
+ outContent="GetHeaders01 PASSED"/>
+
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/GetInputStream01"
outContent="GetInputStream01 PASSED"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/WrappedGetInputStream01"
outContent="GetInputStream01 PASSED"/>
@@ -141,12 +157,12 @@
tested by invoking a protected URI followed by a non-protected URI
-->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/protected/Authentication01"
inHeaders="Authorization:Basic dG9tY2F0OnRvbWNhdA=="
outContent="Authentication01 PASSED"/>
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/protected/Authentication02"
inHeaders="Authorization:Basic dG9tY2F0OnRvbWNhdA=="
outContent="Authentication02 PASSED"/>
@@ -160,11 +176,11 @@
<!-- ========== Other ServletResponse Tests =========================== -->
- <tester host="${host}" port="${port}"
+ <tester host="${host}" port="${port}" protocol="${protocol}" debug="0"
request="${context.path}/SetBufferSize01"
outContent="SetBufferSize01 PASSED"/>
- <tester host="${host}" port="${port}" debug="0"
+ <tester host="${host}" port="${port}" protocol="${protocol}"
request="${context.path}/WrappedSetBufferSize01"
outContent="SetBufferSize01 PASSED"/>
1.3 +287 -1
jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/TestClient.java
Index: TestClient.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/TestClient.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestClient.java 2000/12/22 22:13:07 1.2
+++ TestClient.java 2000/12/26 18:57:44 1.3
@@ -62,8 +62,10 @@
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
+import java.net.Socket;
import java.net.URL;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
@@ -110,7 +112,7 @@
* </ul>
*
* @author Craig R. McClanahan
- * @version $Revision: 1.2 $ $Date: 2000/12/22 22:13:07 $
+ * @version $Revision: 1.3 $ $Date: 2000/12/26 18:57:44 $
*/
public class TestClient extends Task {
@@ -249,6 +251,22 @@
/**
+ * The protocol and version to include in the request, if executed as
+ * a direct socket connection. Lack of a value here indicates that an
+ * HttpURLConnection should be used instead.
+ */
+ protected String protocol = null;
+
+ public String getProtocol() {
+ return (this.protocol);
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+
+ /**
* The request URI to be sent to the server. This value is required.
*/
protected String request = null;
@@ -281,9 +299,29 @@
/**
* Execute the test that has been configured by our property settings.
+ *
+ * @exception BuildException if an exception occurs
*/
public void execute() throws BuildException {
+ if ((protocol == null) || (protocol.length() == 0))
+ executeHttp();
+ else
+ executeSocket();
+
+ }
+
+
+ // ------------------------------------------------------ Protected Methods
+
+
+ /**
+ * Execute the test via use of an HttpURLConnection.
+ *
+ * @exception BuildException if an exception occurs
+ */
+ protected void executeHttp() throws BuildException {
+
// Construct a summary of the request we will be sending
String summary = "[" + method + " " + request + "]";
if (debug >= 1)
@@ -428,6 +466,254 @@
if (throwable != null)
throwable.printStackTrace(System.out);
}
+
+ }
+
+
+ /**
+ * Execute the test via use of a socket with direct input/output.
+ *
+ * @exception BuildException if an exception occurs
+ */
+ protected void executeSocket() throws BuildException {
+
+ // Construct a summary of the request we will be sending
+ String command = method + " " + request + " " + protocol;
+ String summary = "[" + command + "]";
+ if (debug >= 1)
+ System.out.println("RQST: " + summary);
+ boolean success = true;
+ String result = null;
+ Socket socket = null;
+ OutputStream os = null;
+ PrintWriter pw = null;
+ InputStream is = null;
+ Throwable throwable = null;
+ int outStatus = 0;
+ String outMessage = null;
+
+ try {
+
+ // Open a client socket for this request
+ socket = new Socket(host, port);
+ os = socket.getOutputStream();
+ pw = new PrintWriter(os);
+ is = socket.getInputStream();
+
+ // Send the command and content length header (if any)
+ pw.print(command + "\r\n");
+ if (inContent != null) {
+ if (debug >= 1)
+ System.out.println("HEAD: " + "Content-Length: " +
+ inContent.length());
+ pw.print("Content-Length: " + inContent.length() + "\r\n");
+ }
+
+ // Send the specified headers (if any)
+ if (inHeaders != null) {
+ String headers = inHeaders;
+ while (headers.length() > 0) {
+ int delimiter = headers.indexOf("##");
+ String header = null;
+ if (delimiter < 0) {
+ header = headers;
+ headers = "";
+ } else {
+ header = headers.substring(0, delimiter);
+ headers = headers.substring(delimiter + 2);
+ }
+ int colon = header.indexOf(":");
+ if (colon < 0)
+ break;
+ String name = header.substring(0, colon).trim();
+ String value = header.substring(colon + 1).trim();
+ if (debug >= 1)
+ System.out.println("HEAD: " + name + ": " + value);
+ pw.print(name + ": " + value + "\r\n");
+ }
+ }
+ pw.print("\r\n");
+
+ // Send our content (if any)
+ if (inContent != null) {
+ if (debug >= 1)
+ System.out.print("DATA: ");
+ for (int i = 0; i < inContent.length(); i++) {
+ if (debug >= 1)
+ System.out.print(inContent.charAt(i));
+ pw.print(inContent.charAt(i));
+ }
+ }
+ pw.flush();
+
+ // Read the response status and associated message
+ String line = read(is);
+ if (line == null) {
+ outStatus = -1;
+ outMessage = "NO RESPONSE";
+ } else {
+ line = line.trim();
+ if (debug >= 1)
+ System.out.println("RESP: " + line);
+ int space = line.indexOf(" ");
+ if (space >= 0) {
+ line = line.substring(space + 1).trim();
+ space = line.indexOf(" ");
+ }
+ try {
+ if (space < 0) {
+ outStatus = Integer.parseInt(line);
+ outMessage = "";
+ } else {
+ outStatus = Integer.parseInt(line.substring(0, space));
+ outMessage = line.substring(space + 1).trim();
+ }
+ } catch (NumberFormatException e) {
+ outStatus = -1;
+ outMessage = "NUMBER FORMAT EXCEPTION";
+ }
+ }
+ if (debug >= 1)
+ System.out.println("STAT: " + outStatus + " MESG: " +
+ outMessage);
+
+ // Read the response headers (if any)
+ String headerName = null;
+ String headerValue = null;
+ while (true) {
+ line = read(is);
+ if ((line == null) || (line.length() == 0))
+ break;
+ int colon = line.indexOf(":");
+ if (colon < 0) {
+ if (debug >= 1)
+ System.out.println("????: " + line);
+ } else {
+ headerName = line.substring(0, colon).trim();
+ headerValue = line.substring(colon + 1).trim();
+ if (debug >= 1)
+ System.out.println("HEAD: " + headerName + ": " +
+ headerValue);
+ ; // FIXME - record them?
+ }
+ }
+
+ // Acquire the response data (if any)
+ String outData = "";
+ String outText = "";
+ boolean eol = false;
+ if (is != null) {
+ while (true) {
+ int b = is.read();
+ if (b < 0)
+ break;
+ char ch = (char) b;
+ if ((ch == '\r') || (ch == '\n'))
+ eol = true;
+ if (!eol)
+ outData += ch;
+ else
+ outText += ch;
+ }
+ }
+ if (debug >= 1) {
+ System.out.println("DATA: " + outData);
+ if (outText.length() > 2)
+ System.out.println("TEXT: " + outText);
+ }
+
+ // Validate the response against our criteria
+ if (status != outStatus) {
+ success = false;
+ result = "Expected status=" + status + ", got status=" +
+ outStatus;
+ } else if ((message != null) &&
+ !message.equals(outMessage)) {
+ success = false;
+ result = "Expected message='" + message + "', got message='" +
+ outMessage + "'";
+ } else if ((outContent != null) &&
+ !outData.startsWith(outContent)) {
+ success = false;
+ result = outData;
+ }
+
+ } catch (Throwable t) {
+ success = false;
+ result = "Status=" + outStatus +
+ ", Message=" + outMessage;
+ throwable = null;
+ } finally {
+ if (pw != null) {
+ try {
+ pw.close();
+ } catch (Throwable w) {
+ ;
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (Throwable w) {
+ ;
+ }
+ }
+ if (is != null) {
+ try {
+ is.close();
+ } catch (Throwable w) {
+ ;
+ }
+ }
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (Throwable w) {
+ ;
+ }
+ }
+ }
+
+ if (success)
+ System.out.println("OK " + summary);
+ else {
+ System.out.println("FAIL " + summary + " " + result);
+ if (throwable != null)
+ throwable.printStackTrace(System.out);
+ }
+
+ }
+
+
+ /**
+ * Read and return the next line from the specified input stream, with
+ * no carriage return or line feed delimiters. If
+ * end of file is reached, return <code>null</code> instead.
+ *
+ * @param stream The input stream to read from
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ protected String read(InputStream stream) throws IOException {
+
+ StringBuffer result = new StringBuffer();
+ while (true) {
+ int b = stream.read();
+ if (b < 0) {
+ if (result.length() == 0)
+ return (null);
+ else
+ break;
+ }
+ char c = (char) b;
+ if (c == '\r')
+ continue;
+ else if (c == '\n')
+ break;
+ else
+ result.append(c);
+ }
+ return (result.toString());
}
1.1
jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/GetHeaders01.java
Index: GetHeaders01.java
===================================================================
/* ========================================================================= *
* *
* The Apache Software License, Version 1.1 *
* *
* Copyright (c) 1999, 2000 The Apache Software Foundation. *
* All rights reserved. *
* *
* ========================================================================= *
* *
* Redistribution and use in source and binary forms, with or without modi- *
* fication, are permitted provided that the following conditions are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice *
* notice, this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. The end-user documentation included with the redistribution, if any, *
* must include the following acknowlegement: *
* *
* "This product includes software developed by the Apache Software *
* Foundation <http://www.apache.org/>." *
* *
* Alternately, this acknowlegement may appear in the software itself, if *
* and wherever such third-party acknowlegements normally appear. *
* *
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software *
* Foundation" must not be used to endorse or promote products derived *
* from this software without prior written permission. For written *
* permission, please contact <[EMAIL PROTECTED]>. *
* *
* 5. Products derived from this software may not be called "Apache" nor may *
* "Apache" appear in their names without prior written permission of the *
* Apache Software Foundation. *
* *
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= *
* *
* This software consists of voluntary contributions made by many indivi- *
* duals on behalf of the Apache Software Foundation. For more information *
* on the Apache Software Foundation, please see <http://www.apache.org/>. *
* *
* ========================================================================= */
package org.apache.tester;
import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Test retrieval of headers. The client is expected to send two
* "Accept-Language" headers.
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/12/26 18:57:44 $
*/
public class GetHeaders01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/plain");
PrintWriter writer = response.getWriter();
ArrayList values = new ArrayList();
Enumeration headers = request.getHeaders("Accept-Language");
while (headers.hasMoreElements()) {
String header = (String) headers.nextElement();
values.add(header);
}
if (values.size() != 2)
writer.println("GetHeaders01 FAILED - Returned " + values.size()
+ " headers instead of 2");
else if (values.get(0) == values.get(1))
writer.println("GetHeaders01 FAILED - Returned identical values "
+ values.get(0));
else {
int n = 0;
for (int i = 0; i < values.size(); i++) {
if ("en-us".equals((String) values.get(i)))
n++;
else if ("en-gb".equals((String) values.get(i)))
n++;
}
if (n != 2)
writer.println("GetHeaders01 FAILED - Returned unknown values "
+ values.get(0) + " and " + values.get(1));
else
writer.println("GetHeaders01 PASSED");
}
while (true) {
String message = StaticLogger.read();
if (message == null)
break;
writer.println(message);
}
StaticLogger.reset();
}
}
1.3 +20 -0 jakarta-tomcat-4.0/tester/web/WEB-INF/web.xml
Index: web.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat-4.0/tester/web/WEB-INF/web.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- web.xml 2000/12/22 22:13:08 1.2
+++ web.xml 2000/12/26 18:57:44 1.3
@@ -41,6 +41,11 @@
<!-- ========== Filter Mappings ======================================= -->
<filter-mapping>
+ <filter-name>HttpFilter</filter-name>
+ <url-pattern>/WrappedGetHeaders01</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
<filter-name>GenericFilter</filter-name>
<url-pattern>/WrappedGetInputStream01</url-pattern>
</filter-mapping>
@@ -79,6 +84,11 @@
</servlet>
<servlet>
+ <servlet-name>GetHeaders01</servlet-name>
+ <servlet-class>org.apache.tester.GetHeaders01</servlet-class>
+ </servlet>
+
+ <servlet>
<servlet-name>GetInputStream01</servlet-name>
<servlet-class>org.apache.tester.GetInputStream01</servlet-class>
</servlet>
@@ -113,6 +123,16 @@
<servlet-mapping>
<servlet-name>Authentication02</servlet-name>
<url-pattern>/protected/Authentication02</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>GetHeaders01</servlet-name>
+ <url-pattern>/GetHeaders01</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>GetHeaders01</servlet-name>
+ <url-pattern>/WrappedGetHeaders01</url-pattern>
</servlet-mapping>
<servlet-mapping>