import java.net.*;
import java.util.*;
import java.io.*;

/***
 * A tiny web site exerciser.  This hits a list of web pages a number of times and 
 * pauses an amount of time between hits.
 * It should only be used to test your own web site for performance testing.
 * It uses an ini file, "SiteLoader.ini" to set the URLs, the interval between
 * hits and the number of times to repeat the list.
 * The file looks like the following:
 * <xmp>
 * # this is a test sample for mydomain1
 * # written on May 5, 1998
 * Repeat=2
 * Interval=500
 * Verbose=0
 * http://www.mydomain1.com";
 * http://www.mydomain1.com/Index.html";
 * http://www.mydomain1.com/SiteMap.shtml";
 * <xmp>
 * This will loop through all three sites twice and pause 500 milliseconds 
 * in between hits.
 * Please send any bug reports or enhancements to mitch[at]fincher[dot]org
 * @author Mitch Fincher , 1998
**/
///////////////////////////////////////////////////////////////////
public class SiteLoader implements Runnable {
///////////////////////////////////////////////////////////////////
  Vector urlVector = new Vector();
  int Interval; // milliseconds between invoking the next url
  int Repeat; // number of times to loop thru all urls.
  int Verbose; // 0 for quiet and 1 to print incoming lines
  int Retry; // how many times to retry a bad connection

/***
 * 
 * @param inURLVector a vector of sites to hit. each with the complete
 * url, eg, "http://www.cnn.com"
 * @param inInterval time interval in milliseconds
 * @param inRepeat number of times to repeat
**/
///////////////////////////////////////////////////////////////////
public SiteLoader(Vector inURLVector, int inInterval, int inRepeat, int inVerbose, int inRetry)
///////////////////////////////////////////////////////////////////
  {
    urlVector = inURLVector;
    Interval = inInterval;
    Repeat = inRepeat;
    Verbose = inVerbose;
    Retry = inRetry;
  }

////////////////////////////////////////////////////////////////
public void run()
////////////////////////////////////////////////////////////////
  {
    for(int j = 1;j<=Repeat;j++)
      {
	System.err.println("*** SiteLoader Loop " + j + " ***");

	for(int i=0;i<urlVector.size();i++)
	  {
	    System.err.print("  urlVector: " + urlVector.elementAt(i) + "...");
	    System.err.flush();
	    int lines = hitPage((String)urlVector.elementAt(i),Verbose, Retry);
	    System.err.print(" " + lines + " lines. ");
	    System.err.flush();
	    System.err.print("\n     sleeping " + Interval + " msecs...");
	    System.err.flush();
	    // sleep
	    try {    Thread.sleep(Interval); }
	    catch(Exception ex){ System.err.println("" + ex);}
	    System.err.print("done.\n");
	    System.err.flush();
	  }
      }
  }

///////////////////////////////////////////////////////////////////
public String toString()
///////////////////////////////////////////////////////////////////
  {
    String desc="";
    desc += "\nurlVector: " + urlVector;
    desc += "\nInterval: " + Interval;
    desc += "\nRepeat: " + Repeat;
    desc += "\nVerbose: " + Verbose;
    desc += "\nRetry: " + Retry;

    return(desc);
  }


/***
 * Opens a connection to a URL and reads the data.
 * @param addressString complete URL, eg, "http://www.cnn.com".
 * @returns number of lines read.
**/
///////////////////////////////////////////////////////////////////
static public int hitPage(String addressString, int verbose, int retry)
///////////////////////////////////////////////////////////////////
  {
    int count=0;
    Socket s = null;
    String line = new String();
    URL tempURL=null;
    try {
      tempURL = new URL(addressString);
    } catch (Exception ex)
      { System.out.println("Exception thrown: " + ex); }
    //System.out.println("tempURL: " + tempURL);

     String request   = 
      "GET "+ tempURL.getFile() + " HTTP/1.1\n"
      + "Host: www.traviscad.org:80\n"
      + "Accept: */*\n"
      + "User-Agent: CestMoiqqq/1.0\n"
      + "\n"
      ;
     //if(verbose == 1)
     // System.out.println("request:\n" + request);
    DataInputStream sin=null;
    PrintStream     sout=null;

     try {
         // Create a socket to communicate to the specified host and port.
         s = new Socket(tempURL.getHost(),80);
         // Create streams for reading and writing lines of text
         // from and to this socket.
	 s.setSoTimeout(5000); 
         sin  = new DataInputStream(s.getInputStream());
	 sout = new PrintStream(s.getOutputStream());
     }
    catch (Exception ex)
       {
	 System.out.println("SocketException1: " + ex);
       }

         // Send HTTP request to the server.
    try {Thread.sleep(500); }catch(Exception ex2){ }
    try {
      sout.print(request);sout.flush();

      // Listen for an HTTP reply from the server.
         while(true) {
           // Read a line from the server.
           line = sin.readLine();
	   count++;
	   if(verbose == 1)
	     System.out.println(line);System.out.flush();
           // Check if connection is closed (i.e. for EOF).
           // If it is, close the connection.
           if (line == null) {
	     sin.close();
	     break;
           // Otherwise, add the line to to response.
           }
         } // while
     }
     // try
     catch (java.net.SocketException ex)
       {
	 System.out.println("SocketException: " + ex);
	 System.out.println("I will sleep and retry for " + retry + " times.");
	    try {Thread.sleep(5000); }catch(Exception ex2){ }
	 if(retry > 0)
	   hitPage(addressString, verbose, --retry);
	 else if(retry == 0)
	   System.out.println("FailedToGet: " + addressString);

       }
     catch (Exception ex)
       { System.out.println("Exception thrown: " + ex); }
     // Always be sure to close the socket.
     finally {
       try {
	 System.out.println("finally s: " + s);
	 if (s != null) s.close();
	 s = null;
	 System.gc(); 
       }
       catch (Exception ex)
	 { System.out.println("Exception thrown: " + ex); }
     }
     return(count);
  } // hitPage

///////////////////////////////////////////////////////////////////
public static void help()
///////////////////////////////////////////////////////////////////
  {
    String desc = "";
    desc += "SiteLoader help ";
    desc += "\n\n SiteLoader lets you exercise your website to determine performance.";
    desc += "\nThe URLs to hit, frequency, and repeat interval are stored";
    desc += "\nin the \"SiteLoader.ini\" file.";
    desc += "\nthe following is an example of a \"SiteLoader.ini\" file:";
    desc += "\n----------------- cut here -----------------";
    desc += "\nRepeat=2";
    desc += "\nInterval=2000";
    desc += "\nVerbose=0";
    desc += "\nhttp://www.mydomain1.com";
    desc += "\nhttp://www.mydomain1.com/Index.html";
    desc += "\nhttp://www.mydomain1.com/SiteMap.shtml";
    desc += "\n--------------------------------------------";
    desc += "\n";
    desc += "\nThis will loop through the URLs twice and pause 2000 milliseconds between each.";

    System.err.println(desc);
  }


///////////////////////////////////////////////////////////////////
public static void main(String args[])
///////////////////////////////////////////////////////////////////
  {
    Vector urlVector = new Vector();
    int Repeat=1,Interval=1000,Verbose=0,Retry=5;
    String filename = "SiteLoader.ini";
    DataInputStream IniFileDataStream=null;
    if(args.length > 0)
      {
	help();
	System.exit(2);
      }
    try { 
      IniFileDataStream = new DataInputStream(new FileInputStream(filename));
    }
    catch ( FileNotFoundException e) 
      {
	System.err.println("no SiteLoader.ini file found.");System.err.flush();
	help();
	System.exit(1);
      }
    String line="";
    try {
      while(line != null)
	{
	  line = IniFileDataStream.readLine();

	  if(line == null)
	    break;
	  else if ( line.indexOf("Repeat=") == 0)
	    { Repeat = Integer.parseInt(line.substring(7)); }
	  else if ( line.indexOf("Interval=") == 0)
	    { Interval = Integer.parseInt(line.substring(9)); }
	  else if ( line.indexOf("Verbose=") == 0)
	    { Verbose = Integer.parseInt(line.substring(8)); }
	  else if ( line.indexOf("Retry=") == 0)
	    { Retry = Integer.parseInt(line.substring(6)); }
	  else if ( line.indexOf("#") == 0)
	    { }
	  else if ( line.length() == 0)
	    { }
	  else
	    urlVector.addElement(line);
	}
    }
    catch(Exception ex)
      {

      }

    SiteLoader app = new SiteLoader(urlVector,Interval,Repeat,Verbose, Retry);
    app.run();

    //System.err.println("app: " + app);

    System.exit(0);
  }


} // class SiteLoader
