You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2001/01/20 20:42:09 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/test Attributes.java Body.java DefaultMatcher.java GTest.java Header.java HttpClient.java Parameter.java Response.java
costin 01/01/20 11:42:09
Added: src/share/org/apache/tomcat/util/test Attributes.java
Body.java DefaultMatcher.java GTest.java
Header.java HttpClient.java Parameter.java
Response.java
Log:
Enhancements ( and cleanup ) of GTest.java.
This is a general-purpose tool ( HttpClient and the Matcher can be
used as beans in many places ). Other enhancements will follow.
The goal is to make it easier to run and add tests, and allow more complex
test cases to be deveolped. Ramesh's changes in watchdog should also be
incorporated.
Historic Note: I wrote the first version of GTest based on previous
tester that was part of tomcat's sanity-test. GTest ( or similar tools)
is used in other projects and ( AFAIK ). It is a nice dream to have a
common jakarta repository for all general-purpose tools and utilities.
The GTest is far for beeing complete ( the current code compiles, but
hasn't been tested ). I'll send a lot of information after I finish
with the code - including ( initial ) docs about how to add tests, how
to run the testsuite, etc.
Testing tomcat ( running and developing tests ) will be _fun_.
Revision Changes Path
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/Attributes.java
Index: Attributes.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* A trivial inter-object communication mechanism, part of the first step
* in modularizing and enhancing GTest.
*
* A more generic and extensible system is needed ( JNDI ? )
*
* ( Part of GTest.)
*/
public class Attributes {
static Hashtable attributeCollections=new Hashtable();
private Attributes() {}
public static Hashtable getAttributes( String collection ) {
Hashtable att=(Hashtable)attributeCollections.get( collection );
if( att==null ) {
att=new Hashtable();
attributeCollections.put( collection, att );
}
return att;
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/Body.java
Index: Body.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* Part of GTest. Simple representation of a request/response body.
* The only trick is addText - it allows to use it in ant in a nice way.
*
*/
public class Body {
String body;
public Body() {}
public Body(String s ) {
addText(s);
}
public void addText(String s ) {
body=s;
}
public void setBody(String s ) {
body=s;
}
public String getBody() {
return body;
}
public String getText() {
return body;
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/DefaultMatcher.java
Index: DefaultMatcher.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
// use regexp ? No, it's better to allow other matchers to be used - RegexpMatch
// will be a separate tool
/**
Part of the GTest application
*/
public class DefaultMatcher {
// Expected response
boolean magnitude=true;
boolean exactMatch=false;
// Match the body against a golden file
String goldenFile;
// Match the body against a string
String responseMatch;
// the response should include the following headers
Hashtable expectHeaders;
// Match request line
String returnCode="";
String description;
int debug;
Response response;
// Results of matching
boolean result=false;
StringBuffer messageSB;
public DefaultMatcher() {
}
// --------------------
public boolean getResult() {
return result;
}
public String getMessage() {
return messageSB.toString();
}
// --------------------
/** The response we'll match against
*/
public void setResponse( Response resp ) {
response=resp;
}
// --------------------
public void setExactMatch(String exact) {
exactMatch=Boolean.valueOf( exact ).booleanValue();
}
/** Description should be in <test description=""/>
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description=description;
}
/** Display debug info
*/
public void setDebug( String debugS ) {
debug=Integer.valueOf( debugS).intValue();
}
/** True if this is a positive test, false for negative
*/
public void setMagnitude( String magnitudeS ) {
magnitude = Boolean.valueOf(magnitudeS).booleanValue();
}
/** Compare with the golden file
*/
public void setGoldenFile( String s ) {
this.goldenFile=s;
}
public void addHeader( Header rh ) {
expectHeaders.put( rh.getName(), rh );
}
/** Verify that response includes the expected headers.
* The value is a "|" separated list of headers to expect.
*/
public void setExpectHeaders( String s ) {
expectHeaders=new Hashtable();
Header.parseHeadersAsString( s, expectHeaders );
}
/** Verify that response match the string
*/
public void setResponseMatch( String s ) {
this.responseMatch=s;
}
/** Verify the response code
*/
public void setReturnCode( String s ) {
this.returnCode=s;
}
// -------------------- Execute the request --------------------
public void execute() {
try {
result=checkResponse( magnitude );
} catch(Exception ex ) {
result=false;
}
}
void log(String s ) {
messageSB.append( s ).append("\r\n");
}
private boolean checkResponse(boolean testCondition)
throws Exception
{
String responseLine=response.getResponseLine();
Hashtable headers=response.getHeaders();
boolean responseStatus = true;
// you can't check return code on http 0.9
if( returnCode != null ) {
boolean match= ( responseLine!=null &&
responseLine.indexOf(returnCode) > -1);
if( match != testCondition ) {
responseStatus = false;
log("ERROR");
log(" Expecting: " + returnCode );
log(" Got : " + responseLine);
}
}
if( expectHeaders != null ) {
// Check if we got the expected headers
if(headers==null) {
log("ERROR no response header, expecting header");
}
Enumeration e=expectHeaders.keys();
while( e.hasMoreElements()) {
String key=(String)e.nextElement();
String value=(String)expectHeaders.get(key);
String respValue=(String)headers.get(key);
if( respValue==null || respValue.indexOf( value ) <0 ) {
log("ERROR expecting header " + key + ":" +
value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
return false;
}
}
}
String responseBody=response.getResponseBody();
if( responseMatch != null ) {
// check if we got the string we wanted
if( responseBody == null ) {
log("ERROR: got no response, expecting " + responseMatch);
return false;
}
if( responseBody.indexOf( responseMatch ) < 0) {
responseStatus = false;
log("ERROR: expecting match on " + responseMatch);
log("GOT: " );
log(responseBody );
}
}
// compare the body
if( goldenFile==null) return responseStatus;
// Get the expected result from the "golden" file.
StringBuffer expResult = getExpectedResult();
// Compare the results and set the status
boolean cmp=true;
if(exactMatch)
cmp=compare(responseBody, expResult.toString() );
else
cmp=compareWeek( responseBody, expResult.toString());
if( cmp != testCondition ) {
responseStatus = false;
log("ERROR (" + cmp + "," + testCondition + ")");
log("====================Expecting: ");
log(expResult.toString());
log("====================Got:");
log(responseBody);
log("====================");
}
return responseStatus;
}
// Parse a file into a String.
private StringBuffer getExpectedResult()
throws IOException
{
StringBuffer expResult = new StringBuffer("NONE");
try {
// InputStream in = this.getClass().getResourceAsStream(goldenFile);
InputStream in = new FileInputStream( goldenFile );
return readBody ( in );
} catch (Exception ex) {
log("\tGolden file not found: " + goldenFile);
return expResult;
}
}
// Compare the actual result and the expected result.
private boolean compare(String str1, String str2) {
if ( str1==null || str2==null) return false;
if ( str1.length() != str2.length() ) {
log("Wrong size " + str1.length() +" " + str2.length() );
return false;
}
for(int i=0; i<str1.length() ; i++ ) {
if (str1.charAt( i ) != str2.charAt( i ) ) {
log("Error at " + i + " " + str1.charAt(1) +
str2.charAt(i));
return false;
}
}
return true;
}
// Compare the actual result and the expected result.
// Original compare - ignores spaces ( because most
// golden files are wrong !)
private boolean compareWeek(String str1, String str2) {
if ( str1==null || str2==null) return false;
StringTokenizer st1=new StringTokenizer(str1);
StringTokenizer st2=new StringTokenizer(str2);
while (st1.hasMoreTokens() && st2.hasMoreTokens()) {
String tok1 = st1.nextToken();
String tok2 = st2.nextToken();
if (!tok1.equals(tok2)) {
log("\tFAIL*** : Rtok1 = " + tok1
+ ", Etok2 = " + tok2);
return false;
}
}
if (st1.hasMoreTokens() || st2.hasMoreTokens()) {
return false;
} else {
return true;
}
}
// XXX return byte [], fix the reading !!!!!
StringBuffer readBody( InputStream input )
{
StringBuffer sb = new StringBuffer();
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 sb;
}
}
return sb;
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/GTest.java
Index: GTest.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/** Test a web application. Will send a http request and
verify the response code, compare the response with a golden
file or find strings.
This class is using the well-known ant patterns.
*/
public class GTest {
HttpClient httpClient=new HttpClient();
DefaultMatcher matcher=new DefaultMatcher();
int debug=0;
String description="No description";
static PrintWriter defaultOutput=new PrintWriter(System.out);
PrintWriter out=defaultOutput;
String outType="text";
boolean failureOnly=false;
public GTest() {
}
// -------------------- GTest behavior --------------------
public void setWriter( PrintWriter pw ) {
out=pw;
}
public static void setDefaultWriter( PrintWriter pw ) {
defaultOutput=pw;
}
/** text, xml, html
*/
public void setOutput( String t ) {
outType=t;
}
/** Report only tests that fail
*/
public void setFailureOnly( String e ) {
failureOnly=Boolean.valueOf(e).booleanValue();
}
// -------------------- Ant patterns --------------------
public HttpClient createHttpClient() {
return httpClient;
}
public void addHttpClient(HttpClient c) {
httpClient=c;
}
public void addDefaultMatcher( DefaultMatcher m ) {
matcher=m;
}
// -------------------- Local properties --------------------
/** Description should be in <test description=""/>
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description=description;
}
/** Display debug info
*/
public void setDebug( String debugS ) {
debug=Integer.valueOf( debugS).intValue();
matcher.setDebug( debugS );
httpClient.setDebug( debugS );
}
// -------------------- Client properties --------------------
public void setHost(String h) {
httpClient.setHost(h);
}
public void setPort(String portS) {
httpClient.setPort( portS );
}
/** Set the port as int - different name to avoid confusing ant
*/
public void setPortInt(int i) {
httpClient.setPortInt(i);
}
/** Do a POST with the specified content
*/
public void setContent(String s) {
httpClient.setContent(s);
}
/** Request line ( will have the host and context path prefix)
*/
public void setRequest( String s ) {
httpClient.setRequestLine(s);
}
/** Send additional headers
* The value is a "|" separated list of headers to send
*/
public void setHeaders( String s ) {
httpClient.setHeaders( s );
}
// -------------------- Matcher properties --------------------
public void setExactMatch(String exact) {
matcher.setExactMatch(exact);
}
/** True if this is a positive test, false for negative
*/
public void setMagnitude( String magnitudeS ) {
matcher.setMagnitude( magnitudeS );
}
/** Compare with the golden file
*/
public void setGoldenFile( String s ) {
matcher.setGoldenFile(s);
}
/** Verify that response includes the expected headers
* The value is a "|" separated list of headers to expect.
*/
public void setExpectHeaders( String s ) {
matcher.setExpectHeaders( s );
}
/** Verify that response match the string
*/
public void setResponseMatch( String s ) {
matcher.setResponseMatch( s );
}
/** Verify the response code
*/
public void setReturnCode( String s ) {
matcher.setReturnCode( s );
}
// -------------------- Execute the request --------------------
public void execute() {
try {
httpClient.execute();
Response resp=httpClient.getResponse();
matcher.setResponse( resp );
matcher.execute();
boolean result=matcher.getResult();
// don't print OKs
if( result && failureOnly ) return;
if( "text".equals(outType) )
textReport( result , null );
if( "html".equals(outType) )
htmlReport( result , null );
if( "xml".equals(outType) )
xmlReport( result , null );
} catch(Exception ex ) {
textReport( false, ex );
}
}
// -------------------- Internal methods --------------------
private void textReport( boolean result, Exception ex ) {
String msg=null;
if( "No description".equals( description ))
msg=" (" + httpClient.getRequestLine() + ")";
else
msg=description + " (" + httpClient.getRequestLine() + ")";
if(result)
out.println("OK " + msg );
else
out.println("FAIL " + msg );
if( ex!=null)
ex.printStackTrace(out);
}
private void htmlReport( boolean result, Exception ex ) {
if( result )
out.println( "OK " );
else
out.println("<font color='red'>FAIL ");
String msg=null;
if( "No description".equals( description ))
msg=" (" + httpClient.getRequestLine() + ")";
else
msg=description + " (" + httpClient.getRequestLine() + ")";
out.println( msg );
if( ! result )
out.println("</font>");
out.println("<br>");
if( ex!=null) {
out.println("<b>Exception</b><pre>");
ex.printStackTrace(out);
out.println("</pre><br>");
}
}
private void xmlReport( boolean result, Exception ex ) {
String msg=null;
if( "No description".equals( description ))
msg=" (" + httpClient.getRequestLine() + ")";
else
msg=description + " (" + httpClient.getRequestLine() + ")";
if(result)
out.println("OK " + msg );
else
out.println("FAIL " + msg );
if( ex!=null)
ex.printStackTrace(out);
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/Header.java
Index: Header.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
// XXX TODO Use the util.http
/**
* Part of GTest
*
*/
public class Header {
String name;
String value;
public Header() {}
public Header( String n, String v ) {
setName(n);
setValue(v);
}
public String getName() {
return name;
}
public void setName(String v) {
this.name = v;
}
public String getValue() {
return value;
}
public void setValue(String v) {
this.value = v;
}
// -------------------- Utils --------------------
// Code from JSERV !!!
/**
* Parse the incoming HTTP request headers, and set the corresponding
* request properties.
*
*
* @exception IOException if an input/output error occurs
*/
public static Hashtable parseHeaders(InputStream is) throws IOException {
Hashtable headers=new Hashtable();
while (true) {
// Read the next header line
String line = HttpClient.read(is);
if ((line == null) || (line.length() < 1)) {
break;
}
Header h=new Header();
h.parseHeaderLine( line );
if( h.getName() == null ) {
System.out.println("ERROR: Wrong Header Line: " + line );
} else {
headers.put( h.getName(), h );
}
// if( debug>0) System.out.println("HEADER: " +line +"X" );
}
return headers;
}
public void parseHeaderLine(String line) {
// Parse the header name and value
int colon = line.indexOf(":");
if (colon < 0) {
return;
}
String name = line.substring(0, colon).trim();
String value = line.substring(colon + 1).trim();
}
public static void parseHeadersAsString( String s, Hashtable headers ) {
StringTokenizer st=new StringTokenizer( s, "|");
while( st.hasMoreTokens() ) {
String tok=st.nextToken();
Header h=new Header();
h.parseHeaderLine( tok );
if( h.getName() !=null )
headers.put( h.getName(), h );
}
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/HttpClient.java
Index: HttpClient.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* Part of GTest - send a Http request. This tool gives a lot
* of control over the request, and is usable with ant ( testing
* is also a part of the build process :-) or other xml-tools
* using similar patterns.
*
*
*/
public class HttpClient {
static String CRLF="\r\n";
String host="localhost";
int port=8080;
int debug=0;
String requestLine;
Hashtable requestHeaders;
Body body;
String requestBody;
// Response resulted from this request
Response response;
public HttpClient() {
}
/** Server that will receive the request
*/
public void setHost(String h) {
this.host=h;
}
/** The port used to send the request
*/
public void setPort(String portS) {
this.port=Integer.valueOf( portS).intValue();
}
/** Set the port as int - different name to avoid confusing introspection
*/
public void setPortInt(int i) {
this.port=i;
}
/** Do a POST with the specified content.
*/
public void setContent(String s) {
body=new Body( s );
}
/** Add content to the request, for POST ( alternate method )
*/
public void addBody( Body b ) {
body=b;
}
public void addHeader( String n, String v ) {
requestHeaders.put(n, new Header( n, v) );
}
/** Add a header to the request
*/
public void addHeader( Header rh ) {
requestHeaders.put( rh.getName(), rh );
}
/** Add headers - string representation, will be parsed
* The value is a "|" separated list of headers to expect.
* It's preferable to use the other 2 methods.
*/
public void setHeaders( String s ) {
requestHeaders=new Hashtable();
Header.parseHeadersAsString( s, requestHeaders );
}
/** Add a parameter to the request
* XXX not implemented
*/
public void addParameter( Parameter rp ) {
}
/** Display debug info
*/
public void setDebug( String debugS ) {
debug=Integer.valueOf( debugS).intValue();
}
/** Verbose request line - including method and protocol
*/
public void setRequestLine( String s ) {
this.requestLine=s;
}
public String getRequestLine( ) {
return requestLine;
}
/** Allow sending a verbose request
*/
public void setVerboseRequest( String s ) {
requestBody=s;
}
/** Alternate method for sending a verbose request
*/
public void addText(String s ) {
requestBody=s;
}
// -------------------- Access the response --------------------
public Response getResponse() {
return response;
}
// -------------------- Execute the request --------------------
public void execute() {
try {
dispatch();
} catch(Exception ex ) {
ex.printStackTrace();
}
}
/**
*/
private void prepareRequest()
throws Exception
{
// explicitely set
if( requestBody != null ) return;
// use the existing info to compose what will be sent to the
// server
StringBuffer sb=new StringBuffer();
sb.append(requestLine).append(CRLF);
// We may test HTTP0.9 behavior. If it's post 1.0, it needs
// a LF
if( requestLine.indexOf( "HTTP/1." ) <0 ) {
requestBody=sb.toString();
return; // nothing to add
}
String contentL=null;
// headers
Enumeration headersE=requestHeaders.elements();
while( headersE.hasMoreElements() ) {
Header h=(Header)headersE.nextElement();
sb.append(h.toString()).append( CRLF );
if( "Content-Length".equals( h.getName() )) {
contentL=h.getValue();
}
}
// If we have a body
if( body != null) {
// If set explicitely ( maybe we're testing bad POSTs )
if( contentL==null ) {
sb.append("Content-Length: ").append( body.getBody().length());
sb.append(CRLF);
}
sb.append(body.getBody());
// no /n at the end -see HTTP specs!
// If we want to test bad POST - set Content-Length
// explicitely.
}
// set the requestBody
requestBody=sb.toString();
}
/** Invoke a request, set headers, responseLine, body
* We use plain socket ( instead of the more convenient URLConnection)
* because we want to check bad http, special strings, etc.
*/
private void dispatch()
throws Exception
{
// connect
Socket s = new Socket( host, port);
s.setSoLinger( true, 1000);
InputStream is= s.getInputStream();
OutputStream os=s.getOutputStream();
OutputStreamWriter out=new OutputStreamWriter(os);
PrintWriter pw = new PrintWriter(out);
// Write the request
try {
os.write(requestBody.getBytes()); // XXX encoding !
os.flush();
} catch (Exception ex1 ) {
response.setThrowable( ex1 );
return;
}
try {
// http 1.0 +
if( requestBody.indexOf( "HTTP/1." ) > -1) {
String responseLine = read( is );
response.setResponseLine( responseLine );
Hashtable headers=Header.parseHeaders( is );
response.setHeaders( headers );
}
StringBuffer result = readBody( is );
if(result!=null)
response.setResponseBody( result.toString() );
} catch( SocketException ex ) {
response.setThrowable( ex );
}
try {
s.close();
} catch(IOException ex ) {
}
}
StringBuffer readBody( InputStream input )
{
StringBuffer sb = new StringBuffer();
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 sb;
}
}
return sb;
}
/**
* Read a line from the specified servlet input stream, and strip off
* the trailing carriage return and newline (if any). Return the remaining
* characters that were read as a string.
*
* @returns The line that was read, or <code>null</code> if end of file
* was encountered
*
* @exception IOException if an input/output error occurred
*/
public static String read(InputStream input) throws IOException {
// Read the next line from the input stream
StringBuffer sb = new StringBuffer();
while (true) {
try {
int ch = input.read();
// log("XXX " + (char)ch );
if (ch < 0) {
if (sb.length() == 0) {
// if(debug>0) log("Error reading line " + ch + " " +
// sb.toString() );
return "";
} else {
break;
}
} else if (ch == '\n') {
break;
}
sb.append((char) ch);
} catch( IOException ex ) {
System.out.println("Error reading : " + ex );
// debug=1;
// if(debug>0) log("Partial read: " + sb.toString());
ex.printStackTrace();
//break;
}
}
// Strip any trailing carriage return
int n = sb.length();
if ((n > 0) && (sb.charAt(n - 1) == '\r')) {
sb.setLength(n - 1);
}
// Convert the line to a String and return it
return (sb.toString());
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/Parameter.java
Index: Parameter.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* Part of GTest
*
*/
public class Parameter {
public Parameter() {}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/util/test/Response.java
Index: Response.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.util.test;
import java.net.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
* Part of GTest.
*
*/
public class Response {
String responseLine;
String responseBody;
Hashtable responseHeaders;
Throwable exception;
public Response() {}
/** Exception thrown during request execution
*/
public void setThrowable( Throwable t ) {
exception=t;
}
public Throwable getThrowable() {
return exception;
}
/**
* Response headers
*/
public Hashtable getHeaders() {
return responseHeaders;
}
public void setHeaders(Hashtable v) {
this.responseHeaders = v;
}
/**
* Get the value of responseBody - the content
*/
public String getResponseBody() {
return responseBody;
}
public void setResponseBody(String v) {
this.responseBody = v;
}
/**
* Get the value of responseLine - the first line of the response
*/
public String getResponseLine() {
return responseLine;
}
public void setResponseLine(String v) {
this.responseLine = v;
}
}