You are viewing a plain text version of this content. The canonical link for it is here.
Posted to watchdog-dev@jakarta.apache.org by sa...@locus.apache.org on 2000/11/03 18:07:26 UTC

cvs commit: jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task CookieController.java DefaultTestReporterjava DefautTestResultjava GTest.java HttpCookie.java RfcDateParser.java SaveGTest SaveGTestWithReporting SaveGtest SaveMe

santosh     00/11/03 09:07:21

  Added:       src/tools/org/apache/tomcat/task CookieController.java
                        DefaultTestReporterjava DefautTestResultjava
                        GTest.java HttpCookie.java RfcDateParser.java
                        SaveGTest SaveGTestWithReporting SaveGtest SaveMe
  Log:
  Source files for building Gtest . Now we shouldn't depend on jakarta-tools for testdriver.jar that contains Gtest.
  
  Revision  Changes    Path
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/CookieController.java
  
  Index: CookieController.java
  ===================================================================
  package org.apache.tomcat.task;
  
  import java.util.*;
  import java.io.*;
  import java.net.URLConnection;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.Vector;
  import java.io.FileReader;
  import java.io.BufferedReader;
  import java.io.FileWriter;
  import java.io.PrintWriter;
  import java.io.IOException;
  import java.net.URL;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyVetoException;
  import java.beans.VetoableChangeListener;
  import java.beans.VetoableChangeSupport;
  
  // import sun.net.www.protocol.http.HttpURLConnection;
  /**
   * Represents a collection of Cookie instances. 
   * <p>
   * Fires events when the cookies have been changed internally. Deals
   * with management of cookies in terms of saving and loading them,
   * and disabling them.
   *
   * @author	Ramesh.Mandava 
   */
  
  public class CookieController {
  
      private VetoableChangeSupport vceListeners;
  
      private int listenerNum = 0;
  
      private static Hashtable cookieJar;
  
      private static boolean initialized = false;
  
      /* public no arg constructor for bean */
      public CookieController() {
  	if (!initialized) {
  	    vceListeners = new VetoableChangeSupport(this);
  	    cookieJar = new Hashtable();
  	    initialized = true;
  	}
      }
  
  /////////////////////////////////////////////////////////////
   /**
       * Records any cookies which have been sent as part of an HTTP response.
       * The connection parameter must be already have been opened, so that
       * the response headers are available.  It's ok to pass a non-HTTP
       * URL connection, or one which does not have any set-cookie headers.
       */
      public void recordAnyCookies(Vector rcvVectorOfCookies , URL url ) {
  
  	if ((rcvVectorOfCookies == null) || ( rcvVectorOfCookies.size()== 0) ) {
  	    // no headers here
  	    return;
  	}	
  	try {
  	/*
          Properties properties = new Properties(); 
  	FileInputStream fin = new FileInputStream("ServerAutoRun.properties");
  	properties.load(fin);
        
  	String cookiepolicy = properties.getProperty("cookie.acceptpolicy");
  	if (cookiepolicy == null || cookiepolicy.equals("none")) {
  	    return;
  	}
  	*/
  
  
  
  
  	for (int hi = 0; hi<rcvVectorOfCookies.size(); hi++) {
  
  		String cookieValue = (String)rcvVectorOfCookies.elementAt(hi) ;
  		recordCookie(url, cookieValue); // What to do here
  	    }
  
  	}
  	catch( Exception e )
  	{
  		System.out.println("exception : " + e );
  	}
      }
  
  
      /**
       * Create a cookie from the cookie, and use the HttpURLConnection to
       * fill in unspecified values in the cookie with defaults.
       */
      public void recordCookie(URL url,
  				     String cookieValue) {
  	HttpCookie cookie = new HttpCookie(url, cookieValue);
  	
  	// First, check to make sure the cookie's domain matches the
  	// server's, and has the required number of '.'s
  	String twodot[]=
  	    {"com", "edu", "net", "org", "gov", "mil", "int"};
  	String domain = cookie.getDomain();
  	if( domain == null )
  	    return;
  	int index = domain.indexOf(':');
  	if (index != -1) {
  	    int portCookie;
  	    try {
  		portCookie = (Integer.valueOf(domain.substring(index+1,domain.length()))).intValue();
  	    } catch (Exception e) {
  		return;
  	    }
  	    portCookie = ( portCookie == -1 ) ? 80 : portCookie;
  	    domain=domain.substring(0,index);
  	}
  	domain.toLowerCase();
  	
  	String host = url.getHost();
  	host.toLowerCase();
  
  	boolean domainOK = host.equals(domain);
  	if( !domainOK && host.endsWith( domain ) ) {
  	    int dotsNeeded = 2;
  	    for( int i = 0; i < twodot.length; i++ ) {
  		if( domain.endsWith( twodot[i] ) ) {
  		    dotsNeeded = 1;
  		}
  	    }
  
  	    int lastChar = domain.length();
  	    for( ; lastChar > 0 && dotsNeeded > 0; dotsNeeded-- ) {
  		lastChar = domain.lastIndexOf( '.', lastChar-1 );
  	    }
  
  	    if( lastChar > 0 )
  		domainOK = true;
  	}
  
  	if( domainOK ) {
  	    recordCookie(cookie);
  
  	}
      }
  
  
      /**
       * Record the cookie in the in-memory container of cookies.  If there
       * is already a cookie which is in the exact same domain with the
       * exact same
       */
      public void recordCookie(HttpCookie cookie) {
  	if (!checkIfCookieOK(cookie)) {
  	    return;
  	}
  	synchronized (cookieJar) {
  	    
  	    String domain = cookie.getDomain().toLowerCase();
  
  	    Vector cookieList = (Vector)cookieJar.get(domain);
  	    if (cookieList == null) {
  		cookieList = new Vector();
  	    }
  
  	    addOrReplaceCookie(cookieList, cookie);
  	    cookieJar.put(domain, cookieList);
  	    
  	}
  
      }
  
      public boolean checkIfCookieOK(HttpCookie cookie) {
  	try {
  	    if (vceListeners != null) {
  		vceListeners.fireVetoableChange("cookie", null, cookie );
  	    }
  	} catch (PropertyVetoException ex) {
  	    return false;
  	}
  	
  	return true;
      }
  
      /**
       * Scans the vector of cookies looking for an exact match with the
       * given cookie.  Replaces it if there is one, otherwise adds
       * one at the end.  The vector is presumed to have cookies which all
       * have the same domain, so the domain of the cookie is not checked.
       * <p>
       * <p>
       * If this is called, it is assumed that the cookie jar is exclusively
       * held by the current thread.
       *
       */
      private void addOrReplaceCookie(Vector cookies,
  				       HttpCookie cookie) {
  	int numCookies = cookies.size();
  
  	String path = cookie.getPath();
  	String name = cookie.getName();
  	HttpCookie replaced = null;
  	int replacedIndex = -1;
  
  	for (int i = 0; i < numCookies; i++) {
  	    HttpCookie existingCookie = (HttpCookie)cookies.elementAt(i);
  	
  	    String existingPath = existingCookie.getPath();
  	    if (path.equals(existingPath)) {
  		String existingName = existingCookie.getName();
  		if (name.equals(existingName)) {
  		    // need to replace this one!
  		    replaced = existingCookie;
  		    replacedIndex = i;
  		    break;
  		}
  	    }
  	}
  	
  	
  	// Do the replace - if cookie has already expired, remove 
  	// the replaced cookie. 
  	if (replaced != null) {
  	    if (cookie.isSaveableInMemory()) {
  		cookies.setElementAt(cookie, replacedIndex);
  		//System.out.println("REPLACED existing cookie with " + cookie);
  	    } else {
  		cookies.removeElementAt(replacedIndex);
  		//System.out.println("Removed cookie b/c or expr " + cookie);
  	    }
  
  	} else { // only save the cookie in memory if it is non persistent
            	 // or not expired.
  	    if (cookie.isSaveableInMemory()) {
  		cookies.addElement(cookie);
  		//System.out.println("RECORDED new cookie " + cookie);
  	    } 
  
  	}
  
      }
  
      public String applyRelevantCookies(URL url ) {
  
         try {	
  		/*
  		Properties properties = new Properties(); 
  		FileInputStream fin = new FileInputStream("ServerAutoRun.properties");
  		properties.load(fin);
  		// check current accept policy instead enableCookies
  		String cookiepolicy = properties.getProperty("cookie.acceptpolicy");
  		if (cookiepolicy == null || cookiepolicy.equals("none")) {
  		    return null;
  		}
  
  		*/
  
  		return applyCookiesForHost(url);
  
  	}
  	catch ( Exception e )
  	{
  		System.out.println("Exception : " +e );
  		return null;
  	}
        
  
  
  
      }
  
      
     /**
       * Host may be a FQDN, or a partial domain name starting with a dot.
       * Adds any cookies which match the host and path to the
       * cookie set on the URL connection.
       */
      private String applyCookiesForHost(URL url ){
  	String cookieString = null;
  	Vector cookieVector = getAllRelevantCookies(url);
  	
  	if (cookieVector != null) {
  
  	    for (Enumeration e = cookieVector.elements(); e.hasMoreElements();) {
  		HttpCookie cookie = (HttpCookie)e.nextElement();
  		if( cookieString == null ) {
  		    cookieString = cookie.getNameValue();
  		} else {
  		    cookieString = cookieString + "; " + cookie.getNameValue();
  		}
  	    }
  	    
  	 /*
  
  	    if( cookieString != null ) {
  		httpConn.setRequestProperty("Cookie", cookieString);
  	 
  //		System.out.println("Returned cookie string: " + cookieString + " for HOST = " + host);
  	     }
  
  	  */
  
  
  	}
  //		System.out.println("Returned cookie string: " + cookieString + " for HOST = " + host);
  	return cookieString;
  	
      }
  
      private Vector getAllRelevantCookies(URL url) {
  	String host = url.getHost();
  	Vector cookieVector = getSubsetRelevantCookies(host, url);
  
  	Vector tempVector;
  	int index;
  
  	while ((index = host.indexOf('.', 1)) >= 0) {
  	    // trim off everything up to, and including the dot.
  	    host = host.substring(index+1);
  	    
              // add onto cookieVector
  	    tempVector = getSubsetRelevantCookies(host,url);
  	    if (tempVector != null ) {
  		for (Enumeration e = tempVector.elements(); e.hasMoreElements(); ) {
  		    if (cookieVector == null) {
  			cookieVector = new Vector(2);
  		    }
  
  		    cookieVector.addElement(e.nextElement());
  
  		}
  	    }
  	}
  	return cookieVector;
      }
  
      private Vector getSubsetRelevantCookies(String host, URL url) {
  
  	Vector cookieList = (Vector)cookieJar.get(host);
  	
  //	System.out.println("getRelevantCookies() .. for host, url " + host +", "+url);
  	Vector cookiePortList = (Vector)cookieJar.get(host+":"+((url.getPort() == -1) ? 80 : url.getPort()));
  	if (cookiePortList != null) {
  	    if (cookieList == null) {
  		cookieList = new Vector(10);
  	    }
  	    Enumeration cookies = cookiePortList.elements(); 
  	    while (cookies.hasMoreElements()) {
  		cookieList.addElement(cookies.nextElement());
  	    }  
  	}
  	
  	    
  	if (cookieList == null) {
  	    return null;
  	}
  
  	String path = url.getFile();
  //	System.out.println("        path is " + path + "; protocol = " + url.getProtocol());
  
  
  	int queryInd = path.indexOf('?');
  	if (queryInd > 0) {
  	    // strip off the part following the ?
  	    path = path.substring(0, queryInd);
  	}
  
  	Enumeration cookies = cookieList.elements();
  	Vector cookiesToSend = new Vector(10);
  
  	while (cookies.hasMoreElements()) {
  	    HttpCookie cookie = (HttpCookie)cookies.nextElement();
  	
  	    String cookiePath = cookie.getPath();
  
  	    if (path.startsWith(cookiePath)) {
  		// larrylf: Actually, my documentation (from Netscape)
  		// says that /foo should
  		// match /foobar and /foo/bar.  Yuck!!!
  
  		if (!cookie.hasExpired()) {
  		    cookiesToSend.addElement(cookie);
  		}
  
  /*
     We're keeping this piece of commented out code around just in
     case we decide to put it back.  the spec does specify the above,
     but it is so disgusting!
  
  		int cookiePathLen = cookiePath.length();
  
  		// verify that /foo does not match /foobar by mistake
  		if ((path.length() == cookiePathLen)
  		    || (path.length() > cookiePathLen &&
  			path.charAt(cookiePathLen) == '/')) {
  		
  		    // We have a matching cookie!
  
  		    if (!cookie.hasExpired()) {
  			cookiesToSend.addElement(cookie);
  		    }
  		}
  */
  	    }
  	}
  
  	// Now, sort the cookies in most to least specific order
  	// Yes, its the deaded bubblesort!! Wah Ha-ha-ha-ha....
  	// (it should be a small vector, so perf is not an issue...)
  	if( cookiesToSend.size() > 1 ) {
  	    for( int i = 0; i < cookiesToSend.size()-1; i++ ) {
  		HttpCookie headC = (HttpCookie)cookiesToSend.elementAt(i);
  		String head = headC.getPath();
  		// This little excercise is a cheap way to get
  		// '/foo' to read more specfic then '/'
  		if( !head.endsWith("/") ) {
  		    head = head + "/";
  		}
  		for( int j = i+1; j < cookiesToSend.size(); j++ ) {
  		    HttpCookie scanC = (HttpCookie)cookiesToSend.elementAt(j);
  		    String scan = scanC.getPath();
  		    if( !scan.endsWith("/") ) {
  			scan = scan + "/";
  		    }
  
  		    int headCount = 0;
  		    int index = -1;
  		    while( (index=head.indexOf('/', index+1)) != -1 ) {
  			headCount++;
  		    }
  		    index = -1;
  
  		    int scanCount = 0;
  		    while( (index=scan.indexOf('/', index+1)) != -1 ) {
  			scanCount++;
  		    }
  
  		    if( scanCount > headCount ) {
  			cookiesToSend.setElementAt(headC, j);
  			cookiesToSend.setElementAt(scanC, i);
  			headC = scanC;
  			head = scan;
  		    }
  		}
  	    }
  	}
  
  
      return cookiesToSend;
  
      }
  
      /*
       * Writes cookies out to PrintWriter if they are persistent
       * (i.e. have a expr date)
       * and haven't expired. Will remove cookies that have expired as well
       */
      private void saveCookiesToStream(PrintWriter pw) {
  
  	Enumeration cookieLists = cookieJar.elements();
  		
  	while (cookieLists.hasMoreElements()) {
  	    Vector cookieList = (Vector)cookieLists.nextElement();
  
  	    Enumeration cookies = cookieList.elements();
  
  	    while (cookies.hasMoreElements()) {
  		HttpCookie cookie = (HttpCookie)cookies.nextElement();
  		
  		if (cookie.getExpirationDate() != null) {
  		    if (cookie.isSaveable()) {
  			pw.println(cookie);
  		    } else { // the cookie must have expired, 
  			//remove from Vector cookieList
  			cookieList.removeElement(cookie);
  		    }
  		 
  		}   
  	    }
  	}
          // Must print something to the printwriter in the case that 
  	// the cookieJar has been cleared - otherwise the old cookie
  	// file will continue to exist.
  	pw.print("");
      }
  /////////////////////////////////////////////////////////////
      /* adds cookieList to the existing cookie jar*/
      public void addToCookieJar(HttpCookie[] cookieList) {
  
  	if (cookieList != null) {
  	    for (int i = 0; i < cookieList.length; i++) {
  		
  		recordCookie(cookieList[i]);
  	    }
  	}
  
      }
  
      /*adds one cookie to the Cookie Jar */
      public void addToCookieJar(String cookieString, URL docURL) {
  	recordCookie(new HttpCookie(docURL, cookieString));
      }
  
      /* loads the cookies from the given filename */
      public void loadCookieJarFromFile(String cookieFileName) {
  	try {
  	    FileReader fr = new FileReader(cookieFileName);
  	    
  	    BufferedReader in = new BufferedReader(fr);
  
  	    try {
  		String cookieString;
  		while ((cookieString = in.readLine()) != null) {
  		    HttpCookie cookie = new HttpCookie(cookieString);
  		    // Record the cookie, without notification.  We don't
  		    // do a notification for cookies that are read at
  		    // program start-up.
  		    recordCookie(cookie);
  		}
  	    } finally {
  		in.close();
  	    }
  
  	    
  	} catch (IOException e) {
  	    // do nothing; it's not an error not to have persistent cookies
  	}
  
      }
      
      /* saves the cookies to the given file specified by fname */
      public void saveCookieJarToFile(String cookieFileName) {
  	try {
  	    FileWriter fw = new FileWriter(cookieFileName);
  	    PrintWriter pw = new PrintWriter(fw, false);
  
  	    try {
  		saveCookiesToStream(pw);
  	    } finally {
  		pw.close();
  	    }
  
  	} catch (IOException e) {
  	    // REMIND: I18N
  	    System.err.println("Saving cookies failed " + e.getMessage());
  	}
      }
  
      /**
       * Return an array with all of the cookies represented by this
       * jar.  This is useful when the bean is shutting down, and the client
       * wants to make the cookie jar persist.
       */
      public HttpCookie[] getAllCookies() {
  
  	Vector result = new Vector();
  	Hashtable jar;
  	jar = (Hashtable) cookieJar.clone();
  	
  	synchronized (jar) {
  	
  	    for (Enumeration e = jar.elements(); e.hasMoreElements() ;) {
  		Vector v = (Vector) e.nextElement();
  		for (int i = 0; i < v.size(); i++) {
  		    HttpCookie hc = (HttpCookie) v.elementAt(i);
  		    result.addElement(hc);
  		    
  		}
  		
  	    }
  	}
  
  	HttpCookie[] resultA = new HttpCookie[result.size()];
  	for (int i = 0; i < result.size(); i++) {
  	    resultA[i] = (HttpCookie) result.elementAt(i);
  	}
  	return resultA;
      }
  
      /* Gets all cookies that applies for the URL */
      public HttpCookie[] getCookiesForURL(URL url) {
  
  	Vector cookieVector = getAllRelevantCookies(url);
  
  	if (cookieVector == null) {
  	    return null;
  	}
  
  	int i = 0;
  	HttpCookie[] cookieArr = new HttpCookie[cookieVector.size()];
  
  	for (Enumeration e = cookieVector.elements(); e.hasMoreElements(); ) {
  
  	    cookieArr[i++] = (HttpCookie)e.nextElement();
  //	    System.out.println("cookieArr["+(i-1)+"] = " +cookieArr[i-1].toString());
  	}
  	    
  	return cookieArr;
      }
  
      /* this will set the property of enableCookies to isDisabled */
      public void setCookieDisable(boolean isDisabled) {
  
  	// Pending visit back this again
  	try {
  	Properties properties = new Properties();
  	properties.load(new FileInputStream("ServerAutoRun.properties") );
  	
  	
  	properties.put("enableCookies", isDisabled ? "false" : "true");
  	properties.save(new FileOutputStream("ServerAutoRun.properties"),"comments");
  	}
  	catch ( Exception e )
  	{
  		System.out.println("Exception : " + e );
  	}
      }
  
      public void discardAllCookies() {
  	try {
  	    if (vceListeners != null) {
  		vceListeners.fireVetoableChange("cookie", null, null);
  	    }
  	} catch (PropertyVetoException ex) {
  	    
  	}
  	
  	cookieJar.clear();
  	
      }
  
      /* 
       * purges any expired cookies in the Cookie hashtable.
       */
      public void purgeExpiredCookies() {
  	Enumeration cookieLists = cookieJar.elements();
  		
  	while (cookieLists.hasMoreElements()) {
  	    Vector cookieList = (Vector)cookieLists.nextElement();
  
  	    Enumeration cookies = cookieList.elements();
  
  	    while (cookies.hasMoreElements()) {
  		HttpCookie cookie = (HttpCookie)cookies.nextElement();
  		
  		if (cookie.hasExpired()) {
  		    cookieList.removeElement(cookie);
  		}   
  	    }
  	}
  
      }
  
      /*********************
       * Listener methods
       *********************/
  
      /* Add listener to CookieJar. If the first listener registers,
       * add CookieJar's listener to sunw.hotjava.misc.Cookies. This 
       * management done to avoid having unnecessary object retention*/
      public void addVetoableChangeListener(VetoableChangeListener l) {
  	vceListeners.addVetoableChangeListener(l);
  	
      }
  
      /* Removes listener to CookieJar. If there are no more listeners
       * to CookieJar, remove CookieJar's listener to sunw.hotjava.misc.Cookies.
       */
      public void removeVetoableChangeListener(VetoableChangeListener l) {
  	vceListeners.removeVetoableChangeListener(l);
      }
      
  
      /*********
       * Older code that could serve as a reminder for future
       *********/
      /**
       * Predicate function which returns true if the cookie appears to be
       * invalid somehow and should not be added to the cookie set.
       */
      /* This code used to be called in recordCookie(HttpCookie cookie),
         however, I couldn't figure out what it would be good for, so
         I took it out for now. See the misc.Cookies in deleted file
         for more context*/
      private boolean shouldRejectCookie(HttpCookie cookie) {
  	// REMIND: implement per http-state-mgmt Internet Draft
  	return false;
      }
  
  }
  
  
  
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/DefaultTestReporterjava
  
  Index: DefaultTestReporterjava
  ===================================================================
  import java.io.*;
  
  public class DefaultTestReporter 
  {
  
          
  	String resultFileName="watchdogresults.txt";
  
          String contentFormat = "xml";
  
  	PrintWriter out = new PrintWriter(System.out );
  
          public void setContentFormat( String format )
  	{
  		if (( !contentFormat.equals("xml") ) && ( !contentFormat.equals("plain") ))
  		{
  			System.out.println("Un-Supported Content Format. Defaulting to xml");
  			contentFormat = "xml";
  		}
  		else
  		{
  			contentFormat= format;
  		 }
  	 }
  
  	public DefaultTestReporter(  )
  	{
  
  	}
  
  	public  DefaultTestReporter( String fileName )
  	{
  	    	try 
  	    	{
  			resultFileName = fileName;
  			FileOutputStream fout = new FileOutputStream( resultFileName);
  			out = new PrintWriter( fout );
  	    	}
  	    	catch ( Exception ex )
  	    	{
  			System.out.println("Exception while creating resultFile");
  		}
  		
  		
  	}
  
  	
  
  }
  
  
  
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/DefautTestResultjava
  
  Index: DefautTestResultjava
  ===================================================================
  public class DefaultTestResult  
  {
        	String testName;
        	String testDescription;
        	String testResult;
        	String errorDescription;
  
     	public String getTestName( )
     	{
  		return testName;
     	}
  	
   	public String getTestDescription( )
  	{
  		return testDescription;
  	}
  	
  	public String getTestResult( )
  	{
  		return testResult;
  	}
  
  	public String getErrorDescription() 
  	{
  		return errorDescription;
  	}
  
     	public void setTestName( String testName )
     	{
  		this.testName=testName;
     	}
  
     	public void setTestDescription( String testDescription )
     	{
  		this.testDescription=testDescription;
     	}
     	public void setTestResult( String testResult )
     	{
  		this.testResult=testResult;
     	}
     	public void setErrorDescription( String errorDescription )
     	{
  		this.errorDescription=errorDescription;
     	}
  
  	public Result( String testName, String testDescription,String testResult )
  	{
  		this.testName = testName;
  		this.testDescription = testDescription;
  		this.testResult = testResult;
  	}
  
  	public Result( String testName, String testDescription,String testResult,String errorDescription )
  	{
  		this.testName = testName;
  		this.testDescription = testDescription;
  		this.testResult = testResult;
  		this.errorDescription = errorDescription;
  	}
  
  
  }
  
  
  
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/GTest.java
  
  Index: GTest.java
  ===================================================================
  /**
   * 
   * @Author Costin, Ramesh.Mandava
   *
   */
  package org.apache.tomcat.task;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  // derived from Jsp
  public class GTest  {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // 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="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
  
      // For Report generation
  	static String resultFileName=null;
  	static FileOutputStream resultOut=null;
  	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 ; 
  
  
  
  
  	public void setTestSession( String sessionName )
  	{
  		testSession= sessionName;
  		if ( sessionHash==null)
  		{
  			sessionHash= new Hashtable();
  		}
  		else if ( sessionHash.get( sessionName) == null )
  		{
  			sessionHash.put ( sessionName, new CookieController() );
  		}
  	}
  	
  	public void setTestName ( String tn )
  		throws IOException
  	{
  		testName=tn;
  	}
  
  	public void setAssertion ( String assertion )
  		throws IOException
  	{
  		this.assertion = assertion;
  	}
  	public void setTestStrategy ( String strategy )
  		throws IOException
  	{
  		testStrategy = strategy;
  	}
  	
  	public String getTestName( )
  	{
  		return testName;
  	}
  	public String getAssertion( )
  	{
  		return assertion;
  	}
  	public String getTestStrategy( )
  	{
  		return testStrategy;
  	}
  
  	public void setResultFileName( String fileName )
  		throws IOException
  	{
  	  if ( firstTask )
  	  {
  		resultFileName = fileName;
  		File passedFile= new File( fileName );
  		System.out.println("Full Path of Result File-> " + passedFile.getAbsolutePath() );
  		resultOut = new FileOutputStream( passedFile);
  		if ( resultOut == null )
  		{
  			System.out.println("ERROR: Not able to create FileOutputStream for result");
  		}
  		else
  		{
  			resultOut.write("<root>\n".getBytes() );
  		}
  	  }
  	  
  	}
  	public void setFirstTask( boolean val )
  	{
  		firstTask=val;
  	}
  	public void setLastTask ( boolean val )
  		throws IOException
  	{
  		lastTask=val;
  			
  	}
  		
  
      public GTest() {
      }
      
      
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      public void setContent(String s) {
  	this.content=s;
      }
  
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
  	//Ramesh
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	getHeaderDetails( s, expectHeaders );
  
  	//parseHeader( s, expectHeaders );
      }
  
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      public void setRequest ( String s ) throws Exception {
  	this.request=s;
  	String addressString = request.substring( request.indexOf("/"), request.indexOf("HTTP") ).trim();
  	if ( addressString.indexOf("?") > -1 )
  	{
  		addressString = addressString.substring(0, addressString.indexOf("?") ) ;
  	} 	
  	requestURL= new URL("http", host, port, addressString);
      }
      
     public void setReturnCode( String s ) {
  	this.returnCode=s;
      }
  
     public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
  	//Ramesh
      public void setRequestHeaders( String s ) {
         requestHeaders=new Hashtable();
         getHeaderDetails( s, requestHeaders );
         if( debug>0) 
         {
  	       System.out.println("Request Headers -> " );
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  		}
  	}
  	
  	   //parseHeader( s, requestHeaders );
      }
      
      public void execute() throws Exception {
  	
  	try {
  
  	    if ( resultOut != null )
  	    {
  		resultOut.write("<test>".getBytes() );
  		resultOut.write( ("\n<testName>"+ testName + "</testName>").getBytes() );
  		resultOut.write( ("\n<assertion>"+ assertion + "</assertion>").getBytes() );
  		resultOut.write( ("\n<testStrategy>"+ testStrategy + "</testStrategy>\n").getBytes() );
  	    }
  	
  	    dispatch(request, requestHeaders);
  	    //dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if ( resultOut != null )
  		{
  			resultOut.write("<result>PASS</result>\n".getBytes() );
  		}
  
  		if(  "No description".equals( description )) {
  		    System.out.println("OK " + request );
  		}
  		else
  		    System.out.println("OK " + description + " (" + request + ")");
  	    } else {
  		if ( resultOut != null )
  		{
  			resultOut.write("<result>FAIL</result>\n".getBytes() );
  		}
  
  		if(  "No description".equals( description )) {
  		    System.out.println("FAIL " + request );
  		} else
  		    System.out.println("FAIL " + description + " (" + request + ")" );
  	    }
  	   
              if ( resultOut != null )
  	    { 
  		resultOut.write("</test>\n".getBytes() );
  	    	if ( lastTask== true)
  	    	{
  			resultOut.write("</root>\n".getBytes() );
  			resultOut.close();
  	    	}
  	    }
  
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		System.out.println("FAIL " + request );
  	    } else
  		System.out.println("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  				responseStatus = false;
  				System.out.println("ERROR in: " + request);
  				System.out.println("    Expecting: " + returnCode );
  				System.out.println("    Got      : " + responseLine);
  				if ( resultOut != null )
  				{
  					expectedString = "<expectedReturnCode>" + returnCode + "</expectedReturnCode>\n";
  					actualString = "<actualReturnCode>"+ responseLine + "</actualReturnCode>\n";
  					resultOut.write(expectedString.getBytes() );
  					resultOut.write(actualString.getBytes() );
  		
  	    			}
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		System.out.println("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 ) {
  		    System.out.println("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  			if ( resultOut != null )
  			{
  				expectedString = "<expectedHeader>" + key + ":"+ value + "</expectedHeader>\n";
  				actualString = "<actualHeader>"+ key + ":" + respValue + "</actualHeader>\n";
  				resultOut.write(expectedString.getBytes() );
  				resultOut.write(actualString.getBytes() );
  	
  			}
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		System.out.println("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		System.out.println("ERROR: expecting match on " + responseMatch);
  		System.out.println("GOT: " );
  		System.out.println(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;
  	    System.out.println("ERROR (" + cmp + "," + testCondition + ")in : " + request);
  	    System.out.println("====================Expecting: ");
  	    System.out.println(expResult);
  	    System.out.println("====================Got:");
  	    System.out.println(responseBody);
  	    System.out.println("====================");
  		if ( resultOut != null )
  		{
  			expectedString = "<expectedBody>" + expResult + "</expectedBody>\n";
  			actualString = "<actualBody>"+ responseBody + "</actualBody>\n";
  			resultOut.write(expectedString.getBytes() );
  			resultOut.write(actualString.getBytes() );
  
  		}
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    // Now sending any specified request headers
  	    if ( requestHeaders != null )
  	    {
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			if ( debug >0 )
  			{
  			     System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  			}
  			pw.println( headerKey + ":" + requestHeaders.get( headerKey)); 
  		}
  	    }
  	    if  ( testSession != null )
  	    {
  		cookieController = (CookieController)sessionHash.get( testSession );
  		if ( cookieController != null )
  		{
  
  			String releventCookieString= cookieController.applyRelevantCookies(requestURL );
  			if ( ( releventCookieString != null ) && (!releventCookieString.trim().equals("" ) ) )
  			{
  				String cookieHeader= "Cookie : " + releventCookieString ;
  				if ( debug >0 )
  				{
  				     System.out.println( "Sending Cookie Header:: "  + cookieHeader ); 
  				}
  				pw.println( cookieHeader );
  			}
  		}
  
  	     }
  	    /*
   
  	    if ( ( testSession != null ) && ( sessionHash.get( testSession ) != null ) )
  	    {
  		System.out.println("Sending Session Id : " + (String)sessionHash.get( testSession ) );
  		pw.println("JSESSIONID:" + (String)sessionHash.get( testSession) );
  	    }
  
  	    */
  
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    System.out.println("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) System.out.println("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) System.out.println("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    System.out.println("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // 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) {
              System.out.println("\tGolden file not found: " + goldenFile);
              return expResult;
          }
      }
  
  
      // Compare the actual result and the expected result.
      private boolean compare(String str1, String str2) {
  	//System.out.println("In compare");
  	if ( str1==null || str2==null) return false;
  	if ( str1.length() != str2.length() ) {
  	    System.out.println("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		System.out.println("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) {
  	//System.out.println("In compareWeek");
   	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)) {
  		System.out.println("\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;
      }
  
  	//Ramesh
      private void getHeaderDetails( String line, Hashtable headerHash )
  	{
  		StringTokenizer stk = new StringTokenizer( line, "##" );
  		while ( stk.hasMoreElements( ) )
  		{
  			String presentHeader = stk.nextToken();
  			parseHeader( presentHeader, headerHash );
  		}
  	}
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	cookieVector = new Vector();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) System.out.println("HEADER: " +line +"X" );
  
  	}
  	if ( testSession != null ) 
  	{
  		cookieController = (CookieController)sessionHash.get(testSession);
  		if ( cookieController != null )
  		{
  			cookieController.recordAnyCookies(cookieVector,requestURL);
  		}
  	}
  
  	return headers;
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    System.out.println("ERROR: Wrong Header Line: " +  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);
  	headers.put(name, value);
      }
  
      /**
       * 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
       */
      private 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();
  		//		System.out.println("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) System.out.println("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) System.out.println("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-watchdog-4.0/src/tools/org/apache/tomcat/task/HttpCookie.java
  
  Index: HttpCookie.java
  ===================================================================
  package org.apache.tomcat.task;
  
  import java.util.Properties;
  import java.io.*;
  import java.net.URL;
  import java.util.Date;
  import java.util.StringTokenizer;
  
  /**
   * An object which represents an HTTP cookie.  Can be constructed by
   * parsing a string from the set-cookie: header.
   *
   * Syntax: Set-Cookie: NAME=VALUE; expires=DATE;
   *             path=PATH; domain=DOMAIN_NAME; secure
   *
   * All but the first field are optional.
   *
   * @author	Ramesh.Mandava
   */
  
  public class HttpCookie {
      private Date expirationDate = null;
      private String nameAndValue;
      private String path;
      private String domain;
      private boolean isSecure = false;
      private static boolean defaultSet = true;
      private static long defExprTime = 100;
  
      public HttpCookie(String cookieString) {
  	/*
  	System.out.println("Calling default expiration :");
  	getDefaultExpiration();
  	*/
  	parseCookieString(cookieString);
      }
  
      //
      // Constructor for use by the bean
      //
      public HttpCookie(Date expirationDate,
  		      String nameAndValue,
  		      String path,
  		      String domain,
  		      boolean isSecure) {
  	this.expirationDate = expirationDate;
  	this.nameAndValue = nameAndValue;
  	this.path = path;
  	this.domain = domain;
  	this.isSecure = isSecure;
      }
  
      public HttpCookie(URL url, String cookieString) {
  	parseCookieString(cookieString);
  	applyDefaults(url);
      }
  
      /**
       * Fills in default values for domain, path, etc. from the URL
       * after creation of the cookie.
       */
      private void applyDefaults(URL url) {
  	if (domain == null) {
  	    domain = url.getHost()+":"+((url.getPort() == -1) ? 80 : url.getPort());
  	}
  
  	if (path == null) {
  	    path = url.getFile();
  
  	    // larrylf: The documentation for cookies say that the path is
  	    // by default, the path of the document, not the filename of the
  	    // document.  This could be read as not including that document
  	    // name itself, just its path (this is how NetScape intrprets it)
  	    // so amputate the document name!
  	    int last = path.lastIndexOf("/");
  	    if( last > -1 ) {
  		path = path.substring(0, last);
  	    }
  	}
      }
  
  
      /**
       * Parse the given string into its individual components, recording them
       * in the member variables of this object.
       */
      private void parseCookieString(String cookieString) {
  	StringTokenizer tokens = new StringTokenizer(cookieString, ";");
  
  	if (!tokens.hasMoreTokens()) {
  	    // REMIND: make this robust against parse errors
  	    nameAndValue="=";
  	    return;
  	}
  
  	nameAndValue = tokens.nextToken().trim();
  	
  	while (tokens.hasMoreTokens()) {
  	    String token = tokens.nextToken().trim();
  	
  	    if (token.equalsIgnoreCase("secure")) {
  		isSecure = true;
  	    } else {
  		int equIndex = token.indexOf("=");
  		
  		if (equIndex < 0) {
  		    continue;
  		    // REMIND: malformed cookie
  		}
  		
  		String attr = token.substring(0, equIndex);
  		String val = token.substring(equIndex+1);
  		
  		if (attr.equalsIgnoreCase("path")) {
  		    path = val;
  		} else if (attr.equalsIgnoreCase("domain")) {
  		    if( val.indexOf(".") == 0 ) {
  			// spec seems to allow for setting the domain in
  			// the form 'domain=.eng.sun.com'.  We want to
  			// trim off the leading '.' so we can allow for
  			// both leading dot and non leading dot forms
  			// without duplicate storage.
  			domain = val.substring(1);
  		    } else {
  			domain = val;
  		    }
  		} else if (attr.equalsIgnoreCase("expires")) {
  		    expirationDate = parseExpireDate(val);
  		} else {
  		    // unknown attribute -- do nothing
  		}
  	    }
  	}
  
  	// commented the following out, b/c ok to have no expirationDate
  	// that means that the cookie should last only for that particular 
  	// session.
  	//	if (expirationDate == null) {
  	//     	    expirationDate = getDefaultExpiration();
  	//	}
      }
      
      /* Returns the default expiration, which is the current time + default
         expiration as specified in the properties file.
         This uses reflection to get at the properties file, since Globals is 
         not in the utils/ directory 
         */
      private Date getDefaultExpiration() {
  	if (defaultSet == false) {
  	    Properties props = new Properties();
  	    
  	    try {
  		FileInputStream fin = new FileInputStream("ServerAutoRun.properties");
  		props.load( fin );
  		
  		System.out.println("Got properties from ServerAutoRun.properties");
  		props.list(System.out);
  		
  	    } catch (IOException ex) {
  		System.out.println("HttpCookie getDefaultExpiration : ServerAutoRun.properties not found!" + ex);
  	    }
  	    
  		 // defExprTime = props.getProperty("cookies.default.expiration");
  		 defExprTime = Long.parseLong( props.getProperty("cookies.default.expiration") );
  
  	    }
  	    defaultSet = true;
  	  
  	return (new Date(System.currentTimeMillis() + defExprTime));
  	
      }
  
      //======================================================================
      //
      // Accessor functions
      //
  
  
  
       public String getNameValue() {
  	return nameAndValue;
      }
  
      /**
       * Returns just the name part of the cookie
       */
       public String getName() {
  
  	 // it probably can't have null value, but doesn't hurt much
  	 // to check.
  	 if (nameAndValue == null) {
  	     return "=";
  	 }
  	 int index = nameAndValue.indexOf("=");
  	 return (index < 0) ? "=" : nameAndValue.substring(0, index);
       }
  
  
      /**
       * Returns the domain of the cookie as it was presented
       */
       public String getDomain() {
  	// REMIND: add port here if appropriate
  	return domain;
      }
  
       public String getPath() {
  	return path;
      }
  
       public Date getExpirationDate() {
  	return expirationDate;
      }
  
      public boolean hasExpired() {
  	if(expirationDate == null) {
  	    return false;
  	}
  	return (expirationDate.getTime() <= System.currentTimeMillis());
      }
  
      /**
       * Returns true if the cookie has an expiration date (meaning it's
       * persistent), and if the date nas not expired;
       */
      public boolean isSaveable() {
  	return (expirationDate != null)
  	    && (expirationDate.getTime() > System.currentTimeMillis());
      }
  
      public boolean isSaveableInMemory() {
  	return ((expirationDate == null) ||
  		(expirationDate != null && expirationDate.getTime() > System.currentTimeMillis()));
      }
  		
       public boolean isSecure() {
  	return isSecure;
      }
  
      private Date parseExpireDate(String dateString) {
  	// format is wdy, DD-Mon-yyyy HH:mm:ss GMT
  	RfcDateParser parser = new RfcDateParser(dateString);
  	Date theDate = parser.getDate();
  	if (theDate == null) {
  	    // Expire in some intelligent default time
  	    theDate = getDefaultExpiration();
  	}
  	return theDate;
      }
  
      public String toString() {
  
  	String result = (nameAndValue == null) ? "=" : nameAndValue;
  	if (expirationDate != null) {
  	    result += "; expires=" + expirationDate;
  	}
  	
  	if (path != null) {
  	    result += "; path=" + path;
  	}
  
  	if (domain != null) {
  	    result += "; domain=" + domain;
  	}
  
  	if (isSecure) {
  	    result += "; secure";
  	}
  
  	return result;
      }
  }
  
  
  
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/RfcDateParser.java
  
  Index: RfcDateParser.java
  ===================================================================
  package org.apache.tomcat.task;
  
  import java.util.Date;
  import java.util.Locale;
  import java.util.Locale;
  import java.util.StringTokenizer;
  import java.util.TimeZone;
  
  /**
   * A parser for date strings commonly found in http and email headers that
   * follow various RFC conventions.  Given a date-string, the parser will
   * attempt to parse it by trying matches with a set of patterns, returning
   * null on failure, a Date object on success.
   *
   * @author Ramesh.Mandava 
   */
  public class RfcDateParser {
      private static final String debugProp = "hotjava.debug.RfcDateParser";
  
      private boolean isGMT = false;
  
      private static boolean usingJDK = false;
  
      static final String[] standardFormats = {
  	"EEEE', 'dd-MMM-yy HH:mm:ss z",   // RFC 850 (obsoleted by 1036)
  	"EEEE', 'dd-MMM-yy HH:mm:ss",     // ditto but no tz. Happens too often
  	"EEE', 'dd-MMM-yyyy HH:mm:ss z",  // RFC 822/1123
  	"EEE', 'dd MMM yyyy HH:mm:ss z",  // REMIND what rfc? Apache/1.1
  	"EEEE', 'dd MMM yyyy HH:mm:ss z", // REMIND what rfc? Apache/1.1
  	"EEE', 'dd MMM yyyy hh:mm:ss z",  // REMIND what rfc? Apache/1.1
  	"EEEE', 'dd MMM yyyy hh:mm:ss z", // REMIND what rfc? Apache/1.1
  	"EEE MMM dd HH:mm:ss z yyyy",      // Date's string output format
  	"EEE MMM dd HH:mm:ss yyyy",	  // ANSI C asctime format()
  	"EEE', 'dd-MMM-yy HH:mm:ss",      // No time zone 2 digit year RFC 1123
   	"EEE', 'dd-MMM-yyyy HH:mm:ss"     // No time zone RFC 822/1123
      };
  
      /* because there are problems with JDK1.1.6/SimpleDateFormat with
       * recognizing GMT, we have to create this workaround with the following
       * hardcoded strings */
      static final String[] gmtStandardFormats = {
  	"EEEE',' dd-MMM-yy HH:mm:ss 'GMT'",   // RFC 850 (obsoleted by 1036)
  	"EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'",  // RFC 822/1123
  	"EEE',' dd MMM yyyy HH:mm:ss 'GMT'",  // REMIND what rfc? Apache/1.1
  	"EEEE',' dd MMM yyyy HH:mm:ss 'GMT'", // REMIND what rfc? Apache/1.1
  	"EEE',' dd MMM yyyy hh:mm:ss 'GMT'",  // REMIND what rfc? Apache/1.1
  	"EEEE',' dd MMM yyyy hh:mm:ss 'GMT'", // REMIND what rfc? Apache/1.1
  	"EEE MMM dd HH:mm:ss 'GMT' yyyy"      // Date's string output format
      };
  
      String dateString;
  
      public RfcDateParser(String dateString) {
  	this.dateString = dateString.trim();
  	if (this.dateString.indexOf("GMT") != -1) {
  	    isGMT = true;
  	}
  
  	// use java.text.SimpleDateFormat if present
  	try {
  	    Class c = Class.forName("java.text.SimpleDateFormat");
  	    usingJDK = true;
  	} catch (ClassNotFoundException e) {
  	}
  	
      }
  
      public Date getDate() {
  
          if (usingJDK == true) {
  	    int arrayLen = isGMT ? gmtStandardFormats.length : standardFormats.length;
  	    for (int i = 0; i < arrayLen; i++) {
  		Date d = null;
  
  		if (isGMT) {
  		    d = tryParsing(gmtStandardFormats[i]);
  		} else {
  		    d = tryParsing(standardFormats[i]);
  		}
  		if (d != null) {
  		    return d;
  		}
  
  	    }
  
  	    return null;
  
  	}  // end clause "if (usingJDK)"
  
  	return parseNoJDKDate();
  
      }    
  
      private Date tryParsing(String format) {
  
  	java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(format, Locale.US);
  	if (isGMT) {
  	    df.setTimeZone(TimeZone.getTimeZone("GMT"));
  	}
  	try {
  		return df.parse(dateString);
  	} catch (Exception e) {
  	    return null;
  	}
      }
  
      private Date parseNoJDKDate() {
  	// format is wdy, DD-Mon-yyyy HH:mm:ss GMT
  	// or
  	// format is wdy, DD-Mon-yy HH:mm:ss GMT
  	Date fInternalDate = null;
  	
  	try {
  	    fInternalDate  = new Date(dateString);
  	}
  	catch (Exception ex) {
  	}
  	
  	// Apply emergency parsing measures to work around
  	// Y2K 2 digit year date parse bug in java.util.Date
  	// format is wdy, DD-Mon-yy HH:mm:ss GMT
  	
  	if ( fInternalDate == null ) {
  	    String newString = new String();
  	    
  	    StringTokenizer spaces = new StringTokenizer(dateString, " ");
  	    
  	    if ( spaces.countTokens() >= 3 ) {
  		newString = newString.concat(spaces.nextToken());
  		
  		String DDMonyy = spaces.nextToken();
  		int idx = DDMonyy.lastIndexOf('-');
  		String DDMon = DDMonyy.substring(0, idx);
  		
  		if ( idx >= 0 ) {
  		    String year = DDMonyy.substring(idx+1);
  		    
  		    if ( year.length() == 2 ) {
  			
  			try { 
  			    int yearInt = Integer.parseInt(year);
  			    
  			    if ( yearInt < 70 ) {
  				yearInt = yearInt+2000;
  				String newYY = Integer.toString(yearInt);
  				
  				newString = newString.concat(" " + DDMon + "-" + newYY);
  			    }
  			    else {
  				return(null);
  			    }
  			}
  			catch ( Exception ex ) {
  			    return(null);
  			}
  		    }
  		    else {
  			return(null);
  		    }
  		}
  		else {
  		    return(null);
  		}
  
  		while ( spaces.hasMoreTokens() ) {
  		    newString = newString.concat( " " + spaces.nextToken() );
  		}
  
  		try {
  		    fInternalDate  = new Date(newString);
  		}
  		catch (Exception ex) {
  		}
  	    }  // end of if (spaces.countTokens() >= 3)
  	    else {
  		return(null);
  	    }
  	}  // end of if (fInternalDate == null)
  
  	return fInternalDate;
      }
  
  } /* class RfcDateParser */
  
  
  
  1.1                  jakarta-watchdog-4.0/src/tools/org/apache/tomcat/task/SaveGTest
  
  Index: SaveGTest
  ===================================================================
  /**
   * 
   * @Author Costin, Ramesh.Mandava
   *
   */
  package org.apache.tomcat.task;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  // derived from Jsp
  public class GTest  {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // 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="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
      public GTest() {
      }
      
      
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      public void setContent(String s) {
  	this.content=s;
      }
  
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
  	//Ramesh
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	getHeaderDetails( s, expectHeaders );
  
  	//parseHeader( s, expectHeaders );
      }
  
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      public void setRequest( String s ) {
      	//System.out.println("In setRequest:: Request -> " + s );
  	this.request=s;
      }
      
     public void setReturnCode( String s ) {
  	this.returnCode=s;
      }
  
     public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
  	//Ramesh
      public void setRequestHeaders( String s ) {
         requestHeaders=new Hashtable();
         getHeaderDetails( s, requestHeaders );
         if( debug>0) 
         {
  	       System.out.println("Request Headers -> " );
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  		}
  	}
  	
  	   //parseHeader( s, requestHeaders );
      }
      
      public void execute() throws Exception {
  	
  	try {
  	    dispatch(request, requestHeaders);
  	    //dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if(  "No description".equals( description )) {
  		    System.out.println("OK " + request );
  		}
  		else
  		    System.out.println("OK " + description + " (" + request + ")");
  	    } else {
  		if(  "No description".equals( description )) {
  		    System.out.println("FAIL " + request );
  		} else
  		    System.out.println("FAIL " + description + " (" + request + ")" );
  	    }
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		System.out.println("FAIL " + request );
  	    } else
  		System.out.println("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  		responseStatus = false;
  		System.out.println("ERROR in: " + request);
  		System.out.println("    Expecting: " + returnCode );
  		System.out.println("    Got      : " + responseLine);
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		System.out.println("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 ) {
  		    System.out.println("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		System.out.println("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		System.out.println("ERROR: expecting match on " + responseMatch);
  		System.out.println("GOT: " );
  		System.out.println(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;
  	    System.out.println("ERROR (" + cmp + "," + testCondition + ")in : " + request);
  	    System.out.println("====================Expecting: ");
  	    System.out.println(expResult);
  	    System.out.println("====================Got:");
  	    System.out.println(responseBody);
  	    System.out.println("====================");
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    // Now sending any specified request headers
  	    if ( requestHeaders != null )
  	    {
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			if ( debug >0 )
  			{
  			     System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  			}
  			pw.println( headerKey + ":" + requestHeaders.get( headerKey)); 
  		}
  	    }
  
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    System.out.println("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) System.out.println("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) System.out.println("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    System.out.println("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // 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) {
              System.out.println("\tGolden file not found: " + goldenFile);
              return expResult;
          }
      }
  
  
      // Compare the actual result and the expected result.
      private boolean compare(String str1, String str2) {
  	System.out.println("In compare");
  	if ( str1==null || str2==null) return false;
  	if ( str1.length() != str2.length() ) {
  	    System.out.println("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		System.out.println("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) {
  	System.out.println("In compareWeek");
   	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)) {
  		System.out.println("\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;
      }
  
  	//Ramesh
      private void getHeaderDetails( String line, Hashtable headerHash )
  	{
  		StringTokenizer stk = new StringTokenizer( line, "##" );
  		while ( stk.hasMoreElements( ) )
  		{
  			String presentHeader = stk.nextToken();
  			parseHeader( presentHeader, headerHash );
  		}
  	}
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) System.out.println("HEADER: " +line +"X" );
  
  	}
  
  	return headers;
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    System.out.println("ERROR: Wrong Header Line: " +  line );
  	    return;
  	}
  	String name = line.substring(0, colon).trim();
  	String value = line.substring(colon + 1).trim();
  
  	//	System.out.println("HEADER: " +name + " " + value);
  	headers.put(name, value);
      }
  
      /**
       * 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
       */
      private 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();
  		//		System.out.println("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) System.out.println("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) System.out.println("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-watchdog-4.0/src/tools/org/apache/tomcat/task/SaveGTestWithReporting
  
  Index: SaveGTestWithReporting
  ===================================================================
  /**
   * 
   * @Author Costin, Ramesh.Mandava
   *
   */
  package org.apache.tomcat.task;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  // derived from Jsp
  public class GTest  {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // 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="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
  
      // For Report generation
  	static String resultFileName=null;
  	static FileOutputStream resultOut=null;
  	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 ; 
  
  
  
  
  	public void setTestSession( String sessionName )
  	{
  		testSession= sessionName;
  		if ( sessionHash==null)
  		{
  			sessionHash= new Hashtable();
  		}
  		else if ( sessionHash.get( sessionName) == null )
  		{
  			sessionHash.put ( sessionName, new CookieController() );
  		}
  	}
  	
  	public void setTestName ( String tn )
  		throws IOException
  	{
  		testName=tn;
  	}
  
  	public void setAssertion ( String assertion )
  		throws IOException
  	{
  		this.assertion = assertion;
  	}
  	public void setTestStrategy ( String strategy )
  		throws IOException
  	{
  		testStrategy = strategy;
  	}
  	
  	public String getTestName( )
  	{
  		return testName;
  	}
  	public String getAssertion( )
  	{
  		return assertion;
  	}
  	public String getTestStrategy( )
  	{
  		return testStrategy;
  	}
  
  	public void setResultFileName( String fileName )
  		throws IOException
  	{
  	  if ( firstTask )
  	  {
  		resultFileName = fileName;
  		File passedFile= new File( fileName );
  		System.out.println("Full Path of Result File-> " + passedFile.getAbsolutePath() );
  		resultOut = new FileOutputStream( passedFile);
  		if ( resultOut == null )
  		{
  			System.out.println("ERROR: Not able to create FileOutputStream for result");
  		}
  		else
  		{
  			resultOut.write("<root>\n".getBytes() );
  		}
  	  }
  	  
  	}
  	public void setFirstTask( boolean val )
  	{
  		firstTask=val;
  	}
  	public void setLastTask ( boolean val )
  		throws IOException
  	{
  		lastTask=val;
  			
  	}
  		
  
      public GTest() {
      }
      
      
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      public void setContent(String s) {
  	this.content=s;
      }
  
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
  	//Ramesh
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	getHeaderDetails( s, expectHeaders );
  
  	//parseHeader( s, expectHeaders );
      }
  
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      public void setRequest ( String s ) throws Exception {
      	//System.out.println("In setRequest:: Request -> " + s );
  	this.request=s;
  	String addressString = request.substring( request.indexOf("/"), request.indexOf("HTTP") ).trim();
  	requestURL= new URL("http", host, port, addressString);
      }
      
     public void setReturnCode( String s ) {
  	this.returnCode=s;
      }
  
     public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
  	//Ramesh
      public void setRequestHeaders( String s ) {
         requestHeaders=new Hashtable();
         getHeaderDetails( s, requestHeaders );
         if( debug>0) 
         {
  	       System.out.println("Request Headers -> " );
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  		}
  	}
  	
  	   //parseHeader( s, requestHeaders );
      }
      
      public void execute() throws Exception {
  	
  	try {
  
  	    if ( resultOut != null )
  	    {
  		resultOut.write("<test>".getBytes() );
  		resultOut.write( ("\n<testName>"+ testName + "</testName>").getBytes() );
  		resultOut.write( ("\n<assertion>"+ assertion + "</assertion>").getBytes() );
  		resultOut.write( ("\n<testStrategy>"+ testStrategy + "</testStrategy>\n").getBytes() );
  	    }
  	
  	    dispatch(request, requestHeaders);
  	    //dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if ( resultOut != null )
  		{
  			resultOut.write("<result>PASS</result>\n".getBytes() );
  		}
  
  		if(  "No description".equals( description )) {
  		    System.out.println("OK " + request );
  		}
  		else
  		    System.out.println("OK " + description + " (" + request + ")");
  	    } else {
  		if ( resultOut != null )
  		{
  			resultOut.write("<result>FAIL</result>\n".getBytes() );
  		}
  
  		if(  "No description".equals( description )) {
  		    System.out.println("FAIL " + request );
  		} else
  		    System.out.println("FAIL " + description + " (" + request + ")" );
  	    }
  	   
              if ( resultOut != null )
  	    { 
  		resultOut.write("</test>\n".getBytes() );
  	    	if ( lastTask== true)
  	    	{
  			resultOut.write("</root>\n".getBytes() );
  			resultOut.close();
  	    	}
  	    }
  
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		System.out.println("FAIL " + request );
  	    } else
  		System.out.println("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  				responseStatus = false;
  				System.out.println("ERROR in: " + request);
  				System.out.println("    Expecting: " + returnCode );
  				System.out.println("    Got      : " + responseLine);
  				if ( resultOut != null )
  				{
  					expectedString = "<expectedReturnCode>" + returnCode + "</expectedReturnCode>\n";
  					actualString = "<actualReturnCode>"+ responseLine + "</actualReturnCode>\n";
  					resultOut.write(expectedString.getBytes() );
  					resultOut.write(actualString.getBytes() );
  		
  	    			}
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		System.out.println("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 ) {
  		    System.out.println("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  			if ( resultOut != null )
  			{
  				expectedString = "<expectedHeader>" + key + ":"+ value + "</expectedHeader>\n";
  				actualString = "<actualHeader>"+ key + ":" + respValue + "</actualHeader>\n";
  				resultOut.write(expectedString.getBytes() );
  				resultOut.write(actualString.getBytes() );
  	
  			}
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		System.out.println("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		System.out.println("ERROR: expecting match on " + responseMatch);
  		System.out.println("GOT: " );
  		System.out.println(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;
  	    System.out.println("ERROR (" + cmp + "," + testCondition + ")in : " + request);
  	    System.out.println("====================Expecting: ");
  	    System.out.println(expResult);
  	    System.out.println("====================Got:");
  	    System.out.println(responseBody);
  	    System.out.println("====================");
  		if ( resultOut != null )
  		{
  			expectedString = "<expectedBody>" + expResult + "</expectedBody>\n";
  			actualString = "<actualBody>"+ responseBody + "</actualBody>\n";
  			resultOut.write(expectedString.getBytes() );
  			resultOut.write(actualString.getBytes() );
  
  		}
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    // Now sending any specified request headers
  	    if ( requestHeaders != null )
  	    {
  	       Enumeration reqHeaderEnum = requestHeaders.keys();
  	       while ( reqHeaderEnum.hasMoreElements() )
  	       {
  			String headerKey = (String)reqHeaderEnum.nextElement();
  			if ( debug >0 )
  			{
  			     System.out.println( headerKey + "::" + requestHeaders.get(headerKey) ); 
  			}
  			pw.println( headerKey + ":" + requestHeaders.get( headerKey)); 
  		}
  	    }
  	    if  ( testSession != null )
  	    {
  		cookieController = (CookieController)sessionHash.get( testSession );
  		if ( cookieController != null )
  		{
  
  			String releventCookieString= cookieController.applyRelevantCookies(requestURL );
  			if ( ( releventCookieString != null ) && (!releventCookieString.trim().equals("" ) ) )
  			{
  				String cookieHeader= "Cookie : " + releventCookieString ;
  				if ( debug >0 )
  				{
  				     System.out.println( "Sending Cookie Header:: "  + cookieHeader ); 
  				}
  				pw.println( cookieHeader );
  			}
  		}
  
  	     }
  	    /*
   
  	    if ( ( testSession != null ) && ( sessionHash.get( testSession ) != null ) )
  	    {
  		System.out.println("Sending Session Id : " + (String)sessionHash.get( testSession ) );
  		pw.println("JSESSIONID:" + (String)sessionHash.get( testSession) );
  	    }
  
  	    */
  
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    System.out.println("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) System.out.println("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) System.out.println("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    System.out.println("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // 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) {
              System.out.println("\tGolden file not found: " + goldenFile);
              return expResult;
          }
      }
  
  
      // Compare the actual result and the expected result.
      private boolean compare(String str1, String str2) {
  	System.out.println("In compare");
  	if ( str1==null || str2==null) return false;
  	if ( str1.length() != str2.length() ) {
  	    System.out.println("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		System.out.println("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) {
  	System.out.println("In compareWeek");
   	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)) {
  		System.out.println("\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;
      }
  
  	//Ramesh
      private void getHeaderDetails( String line, Hashtable headerHash )
  	{
  		StringTokenizer stk = new StringTokenizer( line, "##" );
  		while ( stk.hasMoreElements( ) )
  		{
  			String presentHeader = stk.nextToken();
  			parseHeader( presentHeader, headerHash );
  		}
  	}
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	cookieVector = new Vector();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) System.out.println("HEADER: " +line +"X" );
  
  	}
  	if ( testSession != null ) 
  	{
  		cookieController = (CookieController)sessionHash.get(testSession);
  		if ( cookieController != null )
  		{
  			cookieController.recordAnyCookies(cookieVector,requestURL);
  		}
  	}
  
  	return headers;
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    System.out.println("ERROR: Wrong Header Line: " +  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);
  	headers.put(name, value);
      }
  
      /**
       * 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
       */
      private 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();
  		//		System.out.println("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) System.out.println("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) System.out.println("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-watchdog-4.0/src/tools/org/apache/tomcat/task/SaveGtest
  
  Index: SaveGtest
  ===================================================================
  /**
   * 
   *
   */
  package org.apache.tomcat.task;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  // derived from Jsp
  public class GTest  {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // 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="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
      public GTest() {
      }
      
      
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	System.out.println("setHost -> " + h );
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	System.out.println("setPort -> " + portS );
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      public void setContent(String s) {
  	this.content=s;
      }
  
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	parseHeader( s, expectHeaders );
      }
  
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      public void setRequest( String s ) {
  	System.out.println("setRequest ");
  	this.request=s;
      }
      
     public void setReturnCode( String s ) {
  	System.out.println("setReturnCode ");
  	this.returnCode=s;
      }
  
     public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
      
      public void execute() throws Exception {
  	
  	try {
  	    System.out.println("Start of execute");
  	    dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if(  "No description".equals( description )) {
  		    System.out.println("OK " + request );
  		}
  		else
  		    System.out.println("OK " + description + " (" + request + ")");
  	    } else {
  		if(  "No description".equals( description )) {
  		    System.out.println("FAIL " + request );
  		} else
  		    System.out.println("FAIL " + description + " (" + request + ")" );
  	    }
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		System.out.println("FAIL " + request );
  	    } else
  		System.out.println("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  		responseStatus = false;
  		System.out.println("ERROR in: " + request);
  		System.out.println("    Expecting: " + returnCode );
  		System.out.println("    Got      : " + responseLine);
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		System.out.println("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 ) {
  		    System.out.println("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		System.out.println("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		System.out.println("ERROR: expecting match on " + responseMatch);
  		System.out.println("GOT: " );
  		System.out.println(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;
  	    System.out.println("ERROR (" + cmp + "," + testCondition + ")in : " + request);
  	    System.out.println("====================Expecting: ");
  	    System.out.println(expResult);
  	    System.out.println("====================Got:");
  	    System.out.println(responseBody);
  	    System.out.println("====================");
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    System.out.println("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) System.out.println("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) System.out.println("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    System.out.println("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // 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) {
              System.out.println("\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() ) {
  	    System.out.println("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		System.out.println("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)) {
  		System.out.println("\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;
      }
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) System.out.println("HEADER: " +line +"X" );
  
  	}
  
  	return headers;
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    System.out.println("ERROR: Wrong Header Line: " +  line );
  	    return;
  	}
  	String name = line.substring(0, colon).trim();
  	String value = line.substring(colon + 1).trim();
  
  	//	System.out.println("HEADER: " +name + " " + value);
  	headers.put(name, value);
      }
  
      /**
       * 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
       */
      private 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();
  		//		System.out.println("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) System.out.println("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) System.out.println("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-watchdog-4.0/src/tools/org/apache/tomcat/task/SaveMe
  
  Index: SaveMe
  ===================================================================
  /**
   * 
   *
   */
  package org.apache.tomcat.task;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  // derived from Jsp
  public class GTest  {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // 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="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
      public GTest() {
      }
      
      
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	System.out.println("setHost -> " + h );
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	System.out.println("setPort -> " + portS );
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      public void setContent(String s) {
  	this.content=s;
      }
  
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	getHeaderInfo( s, expectHeaders );
  //	parseHeader( s, expectHeaders );
      }
  
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      public void setRequest( String s ) {
  	System.out.println("setRequest ");
  	this.request=s;
      }
      
     public void setReturnCode( String s ) {
  	System.out.println("setReturnCode ");
  	this.returnCode=s;
      }
  
     public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
      
      public void execute() throws Exception {
  	
  	try {
  	    System.out.println("Start of execute");
  	    dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if(  "No description".equals( description )) {
  		    System.out.println("OK " + request );
  		}
  		else
  		    System.out.println("OK " + description + " (" + request + ")");
  	    } else {
  		if(  "No description".equals( description )) {
  		    System.out.println("FAIL " + request );
  		} else
  		    System.out.println("FAIL " + description + " (" + request + ")" );
  	    }
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		System.out.println("FAIL " + request );
  	    } else
  		System.out.println("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  		responseStatus = false;
  		System.out.println("ERROR in: " + request);
  		System.out.println("    Expecting: " + returnCode );
  		System.out.println("    Got      : " + responseLine);
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		System.out.println("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 ) {
  		    System.out.println("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		System.out.println("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		System.out.println("ERROR: expecting match on " + responseMatch);
  		System.out.println("GOT: " );
  		System.out.println(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;
  	    System.out.println("ERROR (" + cmp + "," + testCondition + ")in : " + request);
  	    System.out.println("====================Expecting: ");
  	    System.out.println(expResult);
  	    System.out.println("====================Got:");
  	    System.out.println(responseBody);
  	    System.out.println("====================");
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    System.out.println("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) System.out.println("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) System.out.println("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    System.out.println("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // 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) {
              System.out.println("\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() ) {
  	    System.out.println("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		System.out.println("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)) {
  		System.out.println("\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;
      }
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) System.out.println("HEADER: " +line +"X" );
  
  	}
  
  	return headers;
      }
  
      private void getHeaderInfo( String line, Hashtable headers )
      {
  
  	 /** Gets & separated header information into the passed		   headers hashtable.
  	 */
   
  	 StringTokenizer stk = new StringTokenizer( line, "&"  );
  	 while ( stk.hasMoreElements( ) )
  	 {
  		String headerString = stk.nextToken();
  		parseHeader( headerString, headers );
  	 }
  		
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    System.out.println("ERROR: Wrong Header Line: " +  line );
  	    return;
  	}
  	String name = line.substring(0, colon).trim();
  	String value = line.substring(colon + 1).trim();
  
  	//	System.out.println("HEADER: " +name + " " + value);
  	headers.put(name, value);
      }
  
      /**
       * 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
       */
      private 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();
  		//		System.out.println("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) System.out.println("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) System.out.println("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());
      }
  
  }