You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by ms...@apache.org on 2001/06/14 02:28:22 UTC

cvs commit: jakarta-jmeter/src/org/apache/jmeter/protocol/http/save HeaderManagerHandler.java

mstover1    01/06/13 17:28:22

  Modified:    src/org/apache/jmeter/protocol/http/control
                        HttpTestSample.java
               src/org/apache/jmeter/protocol/http/sampler HTTPSampler.java
  Added:       src/org/apache/jmeter/protocol/http/control Header.java
                        HeaderManager.java
               src/org/apache/jmeter/protocol/http/gui HeaderPanel.java
               src/org/apache/jmeter/protocol/http/proxy Admin.java
                        Cache.java Config.java Daemon.java
                        HttpReplyHdr.java HttpRequestHdr.java Proxy.java
               src/org/apache/jmeter/protocol/http/save
                        HeaderManagerHandler.java
  Log:
  New HeaderManager and new proxy service for recording browser actions
  
  Revision  Changes    Path
  1.14      +2 -1      jakarta-jmeter/src/org/apache/jmeter/protocol/http/control/HttpTestSample.java
  
  Index: HttpTestSample.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/org/apache/jmeter/protocol/http/control/HttpTestSample.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- HttpTestSample.java	2001/06/07 23:38:46	1.13
  +++ HttpTestSample.java	2001/06/14 00:28:18	1.14
  @@ -71,7 +71,7 @@
    *  Apache Foundation
    *
    *@author     Michael Stover
  - *@created    $Date: 2001/06/07 23:38:46 $
  + *@created    $Date: 2001/06/14 00:28:18 $
    *@version    1.0
    */
   
  @@ -237,6 +237,7 @@
   	static {
   		addableList.add(new UrlConfig().getClassLabel());
   		addableList.add(new CookieManager().getClassLabel());
  +		addableList.add(new HeaderManager().getClassLabel());
   		addableList.add(new AuthManager().getClassLabel());
   	}
   
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/control/Header.java
  
  Index: Header.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jmeter.protocol.http.control;
  
  import org.apache.jmeter.config.*;
  
  /**
   * This class is an HTTP Header encapsulator.
   *
   * @author  <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
   */
  public class Header extends AbstractConfigElement {
  	 private static String NAME = "name";
  	 private static String VALUE = "value";
  
  	 /**
  	  * create the headeer
  	  */
  	 public Header() {
  		  this.setName("");
  		  this.setValue("");
  	 }
  
  	 /**
  	  * create the coookie
  	  */
  	 public Header(String name, String value) {
  		  this.setName(name);
  		  this.setValue(value);
  	 }
  
  	 public void addConfigElement(ConfigElement config){
  	 }
  
  	 public boolean expectsModification() {
  		  return false;
  	 }
  
  	 public String getClassLabel() {
  		  return "Header";
  	 }
  
  	 /**
  	  * get the value for this object.
  	  */
  	 public String getValue() {
  		  return (String)this.getProperty(VALUE);
  	 }
  
  	 public Object clone() {
  		  Header newConfig = new Header();
  		  configureClone(newConfig);
  		  return newConfig;
  	 }
  
  	 /**
  	  * set the value for this object.
  	  */
  	 public synchronized void setValue(String value) {
  		  this.putProperty(VALUE,value);
  	 }
  
  	 /**
  	  * creates a string representation of this header
  	  */
  	 public String toString() {
  		  return getName() + "\t" + getValue();
  	 }
  }
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/control/HeaderManager.java
  
  Index: HeaderManager.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.jmeter.protocol.http.control;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileReader;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.net.URL;
  import java.text.DateFormat;
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.*;
  import javax.swing.table.AbstractTableModel;
  
  import org.apache.jmeter.config.*;
  import org.apache.jmeter.gui.JMeterComponentModel;
  import org.apache.jmeter.protocol.http.save.*;
  import org.apache.jmeter.save.Saveable;
  
  /**
   * This class provides an interface to headers file to
   * pass HTTP headers along with a request.
   *
   * @author  <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
   * @version $Revision: 1.1 $ $Date: 2001/06/14 00:28:18 $
   */
  public class HeaderManager extends AbstractTableModel implements ConfigElement,JMeterComponentModel,Saveable {
  
  	 public static final String HEADERS = "headers";
  	 /**
  	  * A vector of Headers managed by this class.
  	  * @associates <{org.apache.jmeter.controllers.Header}>
  	  */
  	 private List headers = new ArrayList();
  	 private String name;
  
  	 private final static int columnCount = 2;
  	 private final static String[] columnNames = {"Name","Value"};
  
  	 private static List addableList = new LinkedList();
  
  	 public HeaderManager () {
  	 }
  
  	 public Class getTagHandlerClass() {
  		  return org.apache.jmeter.protocol.http.save.HeaderManagerHandler.class;
  	 }
  
  	 public void uncompile() {
  	 }
  
  	 public Object clone() {
  		  HeaderManager ck = new HeaderManager();
  		  for (int x = 0; x < headers.size(); x++) {
  				ck.add((Header)headers.get(x));
  		  }
  		  ck.setName(this.name);
  		  return ck;
  	 }
  
  	 public boolean expectsModification() {
  		  return false;
  	 }
  
  	 public Collection getAddList() {
  		  return addableList;
  	 }
  
  	 public boolean isEditable() {
  		  return true;
  	 }
  
  	 public Class getGuiClass() {
  		  return org.apache.jmeter.protocol.http.gui.HeaderPanel.class;
  	 }
  
  	 public void setName(String name) {
  		  this.name = name;
  	 }
  
  	 public String getName() {
  		  return this.name;
  	 }
  
  	 /************************************************************
  	  *  This allows config elements to combine and give a "layered" effect. for
  	  *  example, say there are two HTTPConfigElements, which have properties for
  	  *  domain, path, method, and parameters. If element A has everything filled
  	  *  in, but null for domain, and element B is added, which has only domain
  	  *  filled in, then after adding B to A, A will have the domain from B. If A
  	  *  already had a domain, then the correct behavior is for A to ignore the
  	  *  addition of element B.
  	  *
  	  *@param  config  !ToDo
  	  ***********************************************************/
  	 public void addConfigElement(ConfigElement config) {
  		  if (config instanceof HeaderManager) {
  				this.headers.addAll(((HeaderManager)config).getHeaders());
  		  }
  	 }
  
  	 public Collection getHeaders() {
  		  return headers;
  	 }
  
  	 /** required by table model interface */
  	 public int getRowCount() {
  		  return headers.size();
  	 }
  	 /** required by table model interface */
  	 public int getColumnCount() {
  		  return columnCount;
  	 }
  	 /** required by table model interface */
  	 public String getColumnName(int column) {
  		  return columnNames[column];
  	 }
  	 /** required by table model interface */
  	 public Class getColumnClass(int column) {
  		  return columnNames[column].getClass();
  	 }
  	 /** required by table model interface */
  	 public Object getValueAt(int row, int column) {
  		  Header head = (Header) headers.get(row);
  		  if (column == 0) {
  				return head.getName();
  		  } else if (column == 1) {
  				return head.getValue();
  		  }
  		  return null;
  	 }
  
  	 /** save the header data to a file */
  	 public void save(String headFile) throws IOException {
  		  File file = new File(headFile);
  		  if (!file.isAbsolute()) {
  				file = new File(System.getProperty("user.dir") + File.separator + headFile);
  		  }
  		  PrintWriter writer = new PrintWriter(new FileWriter(file));
  		  writer.println("# JMeter generated Header file");
  		  for (int i = 0; i < headers.size(); i++) {
  				Header head = (Header) headers.get(i);
  				writer.println(head.toString());
  		  }
  		  writer.flush();
  		  writer.close();
  	 }
  
  	 /** add header data from a file */
  	 public void addFile (String headerFile) throws IOException {
  		  File file = new File(headerFile);
  		  if (!file.isAbsolute()) {
  				file = new File(System.getProperty("user.dir") + File.separator + headerFile);
  		  }
  		  BufferedReader reader = null;
  		  if (file.canRead()) {
  				reader = new BufferedReader(new FileReader(file));
  		  } else {
  				throw new IOException("The file you specified cannot be read.");
  		  }
  
  		  String line;
  		  while ((line = reader.readLine()) != null) {
  				try {
  					 if (line.startsWith("#") || line.trim().length() == 0) {
  						  continue;
  					 }
  					 String[] st = split(line, "\t"," ");
  					 int name = 0;
  					 int value = 1;
  					 Header header = new Header(st[name], st[value]);
  					 headers.add(header);
  				} catch (Exception e) {
  					 throw new IOException("Error parsing header line\n\t'" + line + "'\n\t" + e);
  				}
  		  }
  		  reader.close();
  	 }
  
  	 /** add a header */
  	 public void add(Header h) {
  		  headers.add(h);
  	 }
  	 /** remove a header */
  	 public void remove(int index) {
  		  headers.remove(index);
  	 }
  
  	 /** return the number headers */
  	 public int size() {
  		  return headers.size();
  	 }
  
  	 /** return the header at index i */
  	 public Header get(int i) {
  		  return (Header) headers.get(i);
  	 }
  
  	 /*
  	 public String getHeaderHeaderForURL(URL url) {
  		  if (!url.getProtocol().toUpperCase().trim().equals("HTTP") &&
  					 ! url.getProtocol().toUpperCase().trim().equals("HTTPS")) {
  				return null;
  		  }
  
  		  StringBuffer sbHeader = new StringBuffer();
  		  for (Iterator enum = headers.iterator(); enum.hasNext();) {
  				Header header = (Header) enum.next();
  				if (url.getHost().endsWith(header.getDomain()) &&
  						  url.getFile().startsWith(header.getPath()) &&
  						  (System.currentTimeMillis() / 1000) <= header.getExpires()) {
  					 if (sbHeader.length() > 0) {
  						  sbHeader.append("; ");
  					 }
  					 sbHeader.append(header.getName()).append("=").append(header.getValue());
  				}
  		  }
  
  		  if (sbHeader.length() != 0) {
  				return sbHeader.toString();
  		  } else {
  				return null;
  		  }
  	 }
  	 */
  
  	 /*
  	 public void addHeaderFromHeader(String headerHeader, URL url) {
  		  StringTokenizer st = new StringTokenizer(headerHeader, ";");
  		  String nvp;
  
  		  // first n=v is name=value
  		  nvp = st.nextToken();
  		  int index = nvp.indexOf("=");
  		  String name = nvp.substring(0,index);
  		  String value = nvp.substring(index+1);
  		  String domain = url.getHost();
  
  		  Header newHeader = new Header(name, value);
  		  // check the rest of the headers
  		  while (st.hasMoreTokens()) {
  				nvp = st.nextToken();
  				nvp = nvp.trim();
  				index = nvp.indexOf("=");
  				if(index == -1) {
  					 index = nvp.length();
  				}
  				String key = nvp.substring(0,index);
  
  				Vector removeIndices = new Vector();
  				for (int i = headers.size() - 1; i >= 0; i--) {
  				Header header = (Header) headers.get(i);
  				if (header == null) {
  					 continue;
  				}
  				if (header.getName().equals(newHeader.getName())) {
  					 removeIndices.addElement(new Integer(i));
  				}
  		  }
  
  		  for (Enumeration e = removeIndices.elements(); e.hasMoreElements();) {
  				index = ((Integer) e.nextElement()).intValue();
  				headers.remove(index);
  		  }
  
  	 }
  	 */
  
  	 public void removeHeaderNamed(String name) {
  		  Vector removeIndices = new Vector();
  		  for (int i = headers.size() - 1; i > 0; i--) {
  				Header header = (Header) headers.get(i);
  				if (header == null) {
  					 continue;
  				}
  				if (header.getName().equals(name)) {
  					 removeIndices.addElement(new Integer(i));
  				}
  		  }
  
  		  for (Enumeration e = removeIndices.elements(); e.hasMoreElements();) {
  				headers.remove(((Integer) e.nextElement()).intValue());
  		  }
  	 }
  
  	 /******************************************************
  	  * Takes a String and a tokenizer character, and returns
  		 a new array of strings of the string split by the tokenizer
  		 character.
  		 @param splittee String to be split
  		 @param splitChar Character to split the string on
  		 @param def Default value to place between two split chars that have
  		 nothing between them
  		 @return Array of all the tokens.
  	  ******************************************************/
  	 public String[] split(String splittee, String splitChar, String def) {
  		  if(splittee == null || splitChar == null) {
  				return new String[0];
  		  }
  		  StringTokenizer tokens;
  		  String temp;
  		  int spot;
  		  while((spot=splittee.indexOf(splitChar + splitChar))!=-1) {
  				splittee=splittee.substring(0, spot + splitChar.length()) + def +
  					 splittee.substring(spot + (1*splitChar.length()), splittee.length());
  		  }
  		  Vector returns=new Vector();
  		  tokens = new StringTokenizer(splittee, splitChar);
  		  while(tokens.hasMoreTokens()) {
  				temp = (String)tokens.nextToken();
  				returns.addElement(temp);
  		  }
  		  String[] values=new String[returns.size()];
  		  returns.copyInto(values);
  		  return values;
  	 }
  
  	 public String getClassLabel() {
  		  return "Header Manager";
  	 }
  }
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/gui/HeaderPanel.java
  
  Index: HeaderPanel.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jmeter.protocol.http.gui;
  
  import javax.swing.*;
  import javax.swing.border.*;
  import javax.swing.table.*;
  import java.awt.*;
  import java.awt.event.*;
  import java.io.*;
  
  import org.apache.jmeter.protocol.http.control.*;
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jmeter.gui.*;
  
  /************************************************************
   *  Allows the user to specify if she needs HTTP header services,
   *  and give parameters
   *  for this service.
   *
   *@author     $Author: mstover1 $
   *@created    $Date: 2001/06/14 00:28:19 $
   *@version    $Revision: 1.1 $
   ***********************************************************/
  public class HeaderPanel extends JPanel implements ModelSupported {
  
  	HeaderManager manager;
  
  	/************************************************************
  	 *  A table to show the authentication information
  	 ***********************************************************/
  	JTable headerTable;
  	NamePanel namePanel;
  
  	/************************************************************
  	 *  Default constructor
  	 ***********************************************************/
  	public HeaderPanel()
  	{
  	}
  
  	/************************************************************
  	 *  !ToDo (Method description)
  	 *
  	 *@param  model  !ToDo (Parameter description)
  	 ***********************************************************/
  	public void setModel(Object model)
  	{
  		manager = (HeaderManager)model;
  		init();
  	}
  
  	public void updateGui()
  	{
  		manager.fireTableDataChanged();
  		namePanel.updateGui();
  	}
  
  	/************************************************************
  	 *  Gets a HeaderManager to manage the file that is currently selected. Null is
  	 *  returned if no file is currently selected. Null will also be returned if
  	 *  there is a problem reading the file while getting the HeaderManager.
  	 *
  	 *@return     !ToDo (Return description)
  	 *@returns    A HeaderManager for the current file, or null
  	 ***********************************************************/
  	public HeaderManager getHeaderMgr()
  	{
  		return manager;
  	}
  
  	/************************************************************
  	 *  Shows the main header configuration panel
  	 ***********************************************************/
  	public void init()
  	{
  		this.setLayout(new VerticalLayout());
  		namePanel = new NamePanel(manager);
  		this.add(namePanel);
  		headerTable = new JTable(manager);
  		headerTable.setCellSelectionEnabled(false);
  		headerTable.setRowSelectionAllowed(true);
  		headerTable.setColumnSelectionAllowed(false);
  		headerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  
  		JPanel main = new JPanel();
  		main.setLayout(new BorderLayout());
  
  		JScrollPane scroller = new JScrollPane(headerTable);
  		JTableHeader tableHeader = headerTable.getTableHeader();
  		scroller.setColumnHeaderView(tableHeader);
  		main.add(scroller);
  
  		JButton add = new JButton("Add");
  		JButton edit = new JButton("Edit");
  		JButton delete = new JButton("Delete");
  		//JButton close = new JButton("Close");
  		JButton load = new JButton("Load");
  		JButton save = new JButton("Save");
  		Dimension d = delete.getPreferredSize();
  		add.setPreferredSize(d);
  		edit.setPreferredSize(d);
  		//close.setPreferredSize(d);
  		load.setPreferredSize(d);
  		save.setPreferredSize(d);
  		HeaderUpdater updater = new HeaderUpdater();
  		add.addActionListener(updater);
  		edit.addActionListener(updater);
  		delete.addActionListener(
  			new ActionListener()
  			{
  				/************************************************************
  				 *  !ToDo (Method description)
  				 *
  				 *@param  e  !ToDo (Parameter description)
  				 ***********************************************************/
  				public void actionPerformed(ActionEvent e)
  				{
  					int row = headerTable.getSelectedRow();
  					if (row >= 0)
  					{
  						manager.remove(row);
  					}
  					manager.fireTableDataChanged();
  				}
  			});
  		load.addActionListener(
  			new ActionListener()
  			{
  				/************************************************************
  				 *  !ToDo (Method description)
  				 *
  				 *@param  e  !ToDo (Parameter description)
  				 ***********************************************************/
  				public void actionPerformed(ActionEvent e)
  				{
  					try
  					{
  						File tmp = FileDialoger.promptToOpenFile()
  								.getSelectedFile();
  						if (tmp != null)
  						{
  							manager.addFile(tmp.getAbsolutePath());
  						}
  					}
  					catch (IOException ex)
  					{
  						ex.printStackTrace();
  					}
  				}
  			});
  
  		save.addActionListener(
  			new ActionListener()
  			{
  				/************************************************************
  				 *  !ToDo (Method description)
  				 *
  				 *@param  e  !ToDo (Parameter description)
  				 ***********************************************************/
  				public void actionPerformed(ActionEvent e)
  				{
  					try
  					{
  						File tmp = FileDialoger.promptToOpenFile()
  								.getSelectedFile();
  						if (tmp != null)
  						{
  							manager.save(tmp.getAbsolutePath());
  						}
  					}
  					catch (IOException ex)
  					{
  						ex.printStackTrace();
  					}
  				}
  			});
  
  		JPanel panel = new JPanel();
  		GridBagLayout g = new GridBagLayout();
  		panel.setLayout(g);
  		GridBagConstraints c = new GridBagConstraints();
  		c.fill = c.NONE;
  		c.gridwidth = 1;
  		c.gridheight = 1;
  		c.gridx = 1;
  		c.gridy = 1;
  		g.setConstraints(add, c);
  		panel.add(add);
  		c.gridx = 2;
  		c.gridy = 1;
  		g.setConstraints(edit, c);
  		panel.add(edit);
  		c.gridx = 3;
  		c.gridy = 1;
  		g.setConstraints(delete, c);
  		panel.add(delete);
  		/*
  		 * c.gridx = 1;
  		 * c.gridy = 2;
  		 * g.setConstraints(close, c);
  		 * panel.add(close);
  		 */
  		c.gridx = 2;
  		c.gridy = 2;
  		g.setConstraints(load, c);
  		panel.add(load);
  		c.gridx = 3;
  		c.gridy = 2;
  		g.setConstraints(save, c);
  		panel.add(save);
  		main.add(panel, "South");
  		this.add(main);
  	}
  
  	/************************************************************
  	 *  Updates a header record
  	 *
  	 *@author     $Author: mstover1 $
  	 *@created    $Date: 2001/06/14 00:28:19 $
  	 *@version    $Revision: 1.1 $
  	 ***********************************************************/
  	class HeaderUpdater implements ActionListener
  	{
  		int index;
  		JTextField nameField = new JTextField(20);
  		JTextField valueField = new JTextField(20);
  		JButton ok = new JButton("Ok");
  		JButton cancel = new JButton("Cancel");
  
  		JDialog updateDialog;
  
  		/************************************************************
  		 *  !ToDo (Constructor description)
  		 ***********************************************************/
  		public HeaderUpdater()
  		{
  		}
  
  		/************************************************************
  		 *  returns the contructed panel containing the header record
  		 *
  		 *@return    !ToDo (Return description)
  		 ***********************************************************/
  		public JPanel getPanel()
  		{
  			JPanel main = new JPanel();
  			GridBagLayout g = new GridBagLayout();
  
  			main.setLayout(g);
  			GridBagConstraints c = new GridBagConstraints();
  			c.fill = c.BOTH;
  			c.gridwidth = 1;
  			c.gridheight = 1;
  			JLabel nameLabel = new JLabel("Name:");
  			c.gridx = 1;
  			c.gridy = 1;
  			g.setConstraints(nameLabel, c);
  			main.add(nameLabel);
  			JLabel valueLabel = new JLabel("Value:");
  			c.gridx = 1;
  			c.gridy = 2;
  			g.setConstraints(valueLabel, c);
  			main.add(valueLabel);
  
  			c.gridx = 2;
  			c.gridy = 1;
  			g.setConstraints(nameField, c);
  			main.add(nameField);
  			c.gridx = 2;
  			c.gridy = 2;
  			g.setConstraints(valueField, c);
  			main.add(valueField);
  
  			JPanel buttons = new JPanel();
  			ok.setPreferredSize(cancel.getPreferredSize());
  			buttons.add(ok);
  			buttons.add(cancel);
  			c.gridwidth = 2;
  			c.gridx = 1;
  			c.gridy = 7;
  			g.setConstraints(buttons, c);
  			main.add(buttons);
  
  			return main;
  		}
  
  		/************************************************************
  		 *  !ToDo (Method description)
  		 *
  		 *@param  e  !ToDo (Parameter description)
  		 ***********************************************************/
  		public void actionPerformed(ActionEvent e)
  		{
  			String command = e.getActionCommand();
  			boolean valid = true;
  			index = -1;
  			if (command.equals("Edit"))
  			{
  				index = headerTable.getSelectedRow();
  				if (index < 0)
  				{
  					valid = false;
  				}
  				else
  				{
  					Header c = manager.get(index);
  					nameField = new JTextField(c.getName(), 20);
  					valueField = new JTextField(c.getValue(), 20);
  					ok = new JButton("Ok");
  					cancel = new JButton("Cancel");
  				}
  			}
  			else if (command.equals("Add"))
  			{
  				nameField = new JTextField(20);
  				valueField = new JTextField(20);
  				ok = new JButton("Ok");
  				cancel = new JButton("Cancel");
  			}
  			if (valid)
  			{
  				if (updateDialog != null)
  				{
  					updateDialog.dispose();
  				}
  				updateDialog = new JDialog();
  				updateDialog.setSize(350, 300);
  
  				ok.addActionListener(
  					new ActionListener()
  					{
  						/************************************************************
  						 *  !ToDo (Method description)
  						 *
  						 *@param  ev  !ToDo (Parameter description)
  						 ***********************************************************/
  						public void actionPerformed(ActionEvent ev)
  						{
  							int i = index;
  							Header c = new Header();
  							if (i >= 0)
  							{
  								c = manager.get(index);
  							}
  							c.setName(nameField.getText());
  							c.setValue(valueField.getText());
  							if (i < 0)
  							{
  								manager.add(c);
  							}
  							manager.fireTableDataChanged();
  							updateDialog.dispose();
  						}
  					});
  				cancel.addActionListener(
  					new ActionListener()
  					{
  						/************************************************************
  						 *  !ToDo (Method description)
  						 *
  						 *@param  ev  !ToDo (Parameter description)
  						 ***********************************************************/
  						public void actionPerformed(ActionEvent ev)
  						{
  							updateDialog.dispose();
  						}
  					});
  				updateDialog.getContentPane().add(getPanel());
  				updateDialog.show();
  			}
  		}
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/Admin.java
  
  Index: Admin.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File Admin.java
  ***
  ***/
  
  import java.net.*;
  import java.io.*;
  
  //
  // Class:     Admin
  // Abstract:  The admin thread listens on admin socket and handle all
  //            communications with the remote administrator.
  //
  
  public class Admin extends Thread
  {
  	//
  	// Member variables
  	//
  
  	ServerSocket adminSocket = null;
  	Socket appletSocket = null;
  	String passwordCandidate = null;
  	DataInputStream in = null;
  	DataOutputStream out = null;
  	Config config = null;
  	Cache cache;
  
  
  	//
  	// Public methods
  	//
  
  	//
  	// Constructor
  	//
  	Admin(Config configObject, Cache cacheManager)
  	{
  		try
  		{
  			config = configObject;
  			cache = cacheManager;
  			adminSocket = new ServerSocket(0);
  			config.setAdminPort(adminSocket.getLocalPort());
  		}
  		catch (IOException e)
  		{
  			System.out.println("Error opening admin socket");
  		}
  	}
  
  
  	//
  	// Handle communications with remote administrator
  	//
  	public void run()
  	{
  		while(true)
  		{
  			try
  			{
  				appletSocket = adminSocket.accept();
  				in = new DataInputStream(appletSocket.getInputStream());
  				out = new DataOutputStream(appletSocket.getOutputStream());
  
  				do
  				{
  					// Read password candidate sent by applet
  					String passwordCandidate = in.readLine();
  
  					// Send applet ack/nack on password
  					if (config.getPassword().equals(passwordCandidate))
  					{
  						out.writeBytes("ACCEPT\n");
  						break;
  					}
  					else
  					{
  						out.writeBytes("REJECT\n");
  					}
  					out.flush();
  				}
  				while (true);
  
  				//
  				// Password is OK, so let's send the administrator the
  				// parameters values and read his new values
  				//
  				while(true)
  				{
  					out.writeBytes(config.toString());
  					out.flush();
  
  					config.parse(in.readLine());
  					System.out.println("Configuration changed by administrator.");
  
  					// Administrator wants to clean the cache
  					if (config.getCleanCache())
  					{
  						cache.clean();
  						config.setCleanCache(false); //no need to clean again
  					}
  				}
  			}
  			catch (Exception e)
  			{
  				//
  				// This line was reached because the administrator closed
  				// the connection with the proxy. That's fine, we are now
  				// available for another administrator to log in.
  				//
  				System.out.println("Connection with administrator closed.");
  			}
  			finally
  			{
  				try
  				{
  					out.close();
  					in.close();
  				}
  				catch(Exception exc)
  				{}
  			}
  		}//while
  	}
  }
  
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/Cache.java
  
  Index: Cache.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File Cache.java
  ***
  ***/
  
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  //
  // Class:     Cache
  // Abstract:  manages all caching activities.
  //
  
  public class Cache
  {
  	//
  	// Members variables
  	//
  
  	String basePath = null;
  	long MinFreeSpace;// in bytes
  	Hashtable htable;
  	Config config;
  
  
  	//
  	// Public methods
  	//
  
  	//
  	// Constructor
  	//
  	public Cache(Config configObject)
  	{
  		//
  		// Initialize variables
  		//
  		config = configObject;
  		MinFreeSpace = 15000;
  		htable = new Hashtable();
  
  		//
  		// Create directory for caching
  		//
  
  		File cacheDir = new File("Cache");
  		cacheDir.mkdirs();
  		basePath = cacheDir.getAbsolutePath();
  
  		//
  		// Delete all files in cache directory
  		//
  		int i;
  		File file = new File(basePath);;
  		String filename;
  
  		// Get list of files in cache direcotry
  		String files[] = file.list();
  
  		// Delete each file found
  		for (i=0; i<files.length; i++)
  		{
  			file = new File(basePath + File.separatorChar + files[i]);
  			file.delete();
  		}
  		config.setFilesCached(0);
  		config.setBytesCached(0);
  		config.setHits(0);
  		config.setMisses(0);
  	}
  
  
  	//
  	// isCachable - check if URL reply should be cached
  	//
  	public boolean IsCachable(String rawUrl)
  	{
  		return (getFileName(rawUrl) != null);
  	}
  
  
  	//
  	// IsCached - Check if we have in cache what the client wants.
  	//
  	public boolean IsCached(String rawUrl)
  	{
  		// Generate filename from URL
  		String filename = getFileName(rawUrl);
  		if (filename == null)
  			return false;
  
  		// Search in hash table
  		if (htable.get(filename) != null)
  			return true;
  
  		return false;
  	}
  
  
  	//
  	// getFileInputStream - When this method is called, it means a cache hit.
  	//   We update the date field in the hash table entry and return a
  	//   FileInputStream object corresponding to the file caching the info.
  	//
  	 public FileInputStream getFileInputStream(String rawUrl)
  	{
  		FileInputStream in = null;
  		try
  		{
  			 String filename = getFileName(rawUrl);
  
  			// Update the hash table entry with current date as value
  			htable.put(filename,new Date());
  
  			in = new FileInputStream(filename);
  		}
  		catch (FileNotFoundException fnf)
  		{
  			try
  
  			{
  				System.out.println("File Not Found:"+getFileName(rawUrl)+" "+fnf);
  			}
  			catch (Exception e)
  			{}
  		}
  		finally
  		{
  			return in;
  		}
  	}
  
  
  	//
  	// getFileoutputStream - When this method is called, it means we're about
  	//   to cache a new object. We generate a file name, and return
  	//   a corresponding FileOutputStream object.
  	//
  	 public FileOutputStream getFileOutputStream(String rawUrl)
  	{
  		FileOutputStream out = null;
  		String filename;
  		try
  		{
  			 filename = getFileName(rawUrl);
  
  			out = new FileOutputStream(filename);
  		}
  		catch (IOException e)
  		{}
  		finally
  		{
  			return out;
  		}
  	}
  
  
  	//
  	// Decrement Cache Free Space (In Bytes)
  	//
  	public synchronized void DecrementFreeSpace(int nbytes, String rawUrl)
  	{
  		config.setBytesCached(config.getBytesCached() + nbytes);
  		if (config.getBytesFree() <= MinFreeSpace)
  			MakeFreeSpace(rawUrl);
  	}
  
  
  	//
  	// Add new entry to hash table
  	//
  	public synchronized void AddToTable(String rawUrl)
  	{
  		String filename = getFileName(rawUrl);
  
  		// Add filename to hash table with the current date as its value
  		htable.put(filename,new Date());
  		config.increaseFilesCached();
  	}
  
  	//
  	// clean - delete the cached files
  	//
  	 public synchronized void clean()
  	{
  		System.out.println("Cleaning the cache...");
  
  		// Enumerate the hash table
  		for (Enumeration keys = htable.keys(); keys.hasMoreElements() ;)
  		{
  			String filename = (String)keys.nextElement();
  			File file = new File(filename);
  			long nbytes = file.length();
  			boolean result = file.delete();
  			if (result == true)
  			{
  				// Delete entry in hash table
  				htable.remove(filename);
  				config.decreaseFilesCached();
  
  				// Increment free space
  				config.setBytesCached(config.getBytesCached() - nbytes);
  			}
  			else
  			{
  				// Another thread holds this file open for writing
  			}
  		}
  		config.setHits(0);
  		config.setMisses(0);
  		System.out.println("Cache is clean.");
  	}
  
  
  	//
  	// Private methods
  	//
  
  	//
  	// MakeFreeSpace - throw LRU file until free space is above min level
  	//
  	private synchronized void MakeFreeSpace(String rawUrl)
  	{
  		String filename,
  				LRUfilename;
  		Date   date,
  				minDate;
  
  		minDate = new Date();
  		while (config.getBytesFree() < MinFreeSpace)
  		{
  			filename = LRUfilename = null;
  			date = null;
  
  			if (htable.isEmpty())
  			{
  				System.out.println("Could not make free space: Hash table empty...");
  				return;
  			}
  
  			//
  			// Enumerate the hash table entries to find the LRU file
  			//
  			for (Enumeration keys = htable.keys(); keys.hasMoreElements() ;)
  			{
  				filename = (String)keys.nextElement();
  				date = (Date)htable.get(filename);
  				if (date.before(minDate))
  					LRUfilename = filename;
  			}
  
  			//
  			// Delete the LRU file
  			//
  			File LRUfile = new File(LRUfilename);
  			long nbytes = LRUfile.length();
  			boolean result = LRUfile.delete();
  			if (result == true)
  			{
  				// Delete entry in hash table
  				htable.remove(LRUfilename);
  				config.decreaseFilesCached();
  
  				// Increment free space
  				config.setBytesCached(config.getBytesCached() - nbytes);
  			}
  			else
  			{
  				// Another thread holds this file open for writing
  				System.out.println("File "+LRUfilename+" could not be deleted...");
  				return;
  			}
  		}
  	}
  
  
  	//
  	// Convert the URL to filename - this method parses the URL and
  	//   generate filename only if the URL is to be cached.
  	//   We do not cache URLs containing '?', "cgi-bin" and
  	//   a list of not-to-cached-URLs as instructed by the proxy administrator.
  	//
  	private String getFileName(String rawUrl)
  	{
  		String filename = basePath + File.separatorChar + rawUrl.substring(7).replace('/','@');
  
  		if (filename.indexOf('?') != -1 || filename.indexOf("cgi-bin") != -1)
  		{
  			return null;
  		}
  
  		return filename;
  	}
  }
  
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/Config.java
  
  Index: Config.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File Config.java
  ***
  ***/
  
  import java.util.*;
  import java.net.*;
  import java.io.*;
  
  
  //
  // Class:     Config
  // Abstract:  Configurable parameters of the proxy. This class is
  //            used by both the applet and the proxy.
  //
  
  class Config
  {
  	//
  	// Member variables
  	//
  	String jmxScriptDir;
  	 private boolean  isFatherProxy;
  	 private String   fatherProxyHost;
  	 private int      fatherProxyPort;
  	 private String[] deniedHosts;
  	 private String   password;
  	private boolean  isCaching;  // enable/disable caching
  	private long 	 cacheSize;  // cache size in bytes
  	 private boolean  cleanCache;
  	 private String[] cacheMasks;
  
  	 private long     filesCached;
  	 private long     bytesCached;
  	 private long     bytesFree;
  	 private long     hits;
  	 private long     misses;
  
  	 private final int defaultProxyPort = 8080;
  	 private final String defaultPassword = "admin";
  	 private final long defaultCacheSize = 1000000;
  
  	private String adminPath;
  	private int    adminPort;
  
  	private String localHost;
  	private String localIP;
  
  	private boolean isAppletContext;
  	private String  separator = " ";
  	private String proxyMachineNameAndPort;
  
  
  	//
  	// Member methods
  	//
  
  	//
  	// Constructor
  	//
  	Config()
  	{
  		filesCached = 0;
  		bytesCached = 0;
  		bytesFree = cacheSize;
  		hits = 0;
  		misses = 0;
  
  		reset();
  	}
  
  	public void setJmxScriptDir(String filename)
  	{
  		jmxScriptDir = filename;
  		File file = new File(System.getProperty("user.dir")+File.separator+jmxScriptDir);
  		file.mkdirs();
  	}
  
  	public String getJmxScriptDir()
  	{
  		return jmxScriptDir;
  	}
  
  	//
  	// Re-initialize
  	//
  	public void reset()
  	{
  		  isFatherProxy = false;
  		  fatherProxyHost = "wwwproxy.ac.il";
  		  fatherProxyPort = defaultProxyPort;
  		  password = defaultPassword;
  		isCaching = true;
  		cacheSize = defaultCacheSize;
  		  cleanCache = false;
  
  		deniedHosts = new String[0];
  		cacheMasks = new String[0];
  	}
  
  
  	//
  	// Set/get methods
  	//
  
  	// Set if we are in the applet or in the proxy
  	public void setIsAppletContext(boolean b)
  	{
  		isAppletContext = b;
  	}
  
  	public void setProxyMachineNameAndPort(String s)
  	{
  		proxyMachineNameAndPort = s;
  	}
  
  	public String getProxyMachineNameAndPort()
  	{
  		return proxyMachineNameAndPort;
  	}
  
  	public int getAdminPort()
  	{
  		return adminPort;
  	}
  
  	public void setAdminPort(int port)
  	{
  		adminPort = port;
  	}
  
  	public void setAdminPath(String path)
  	{
  		adminPath = path;
  	}
  
  	public String getAdminPath()
  	{
  		return adminPath;
  	}
  
  	public void setLocalHost(String host)
  	{
  		localHost = host;
  	}
  
  	public String getLocalHost()
  	{
  		return localHost;
  	}
  
  	public void setLocalIP(String ip)
  	{
  		localIP = ip;
  	}
  
  	public String getLocalIP()
  	{
  		return localIP;
  	}
  
  	boolean getIsCaching()
  	{
  		return isCaching;
  	}
  
  	public synchronized void setIsCaching(boolean caching)
  	{
  		isCaching = caching;
  	}
  
  	public synchronized long getCacheSize()
  	{
  		return cacheSize;
  	}
  	public synchronized void setCacheSize(long size)
  	{
  		cacheSize = size;
  	}
  
  	 public boolean getIsFatherProxy()
  	 {
  		  return isFatherProxy;
  	 }
  
  	 public synchronized void setIsFatherProxy(boolean fatherProxy)
  	 {
  		  isFatherProxy  = fatherProxy;
  	 }
  
  	 public String getFatherProxyHost()
  	 {
  		  return fatherProxyHost;
  	 }
  
  	 public synchronized void setFatherProxyHost(String host)
  	 {
  		  fatherProxyHost = host;
  	 }
  
  	 public int getFatherProxyPort()
  	 {
  		  return fatherProxyPort;
  	 }
  
  	 public synchronized void setFatherProxyPort(int port)
  	 {
  		  fatherProxyPort = port;
  	 }
  
  	 public String[] getDeniedHosts()
  	 {
  		  return deniedHosts;
  	 }
  
  	 public synchronized void setDeniedHosts(String[] hosts)
  	 {
  		  deniedHosts = hosts;
  	 }
  
  	 public String getPassword()
  	 {
  		  return password;
  	 }
  
  	 public synchronized void setPassword(String newPassword)
  	 {
  		  password = newPassword;
  	 }
  
  	 public boolean getCleanCache()
  	 {
  		  return cleanCache;
  	 }
  
  	 public synchronized void setCleanCache(boolean clean)
  	 {
  		  cleanCache = clean;
  	 }
  
  	 public String[] getCacheMasks()
  	 {
  		  return cacheMasks;
  	 }
  
  	 public synchronized void setCacheMasks(String[] masks)
  	 {
  		  cacheMasks = masks;
  	 }
  
  	 public long getFilesCached()
  	 {
  		  return filesCached;
  	 }
  
  	 public synchronized void increaseFilesCached()
  	 {
  		  filesCached++;
  	 }
  
  	 public synchronized void decreaseFilesCached()
  	 {
  		  filesCached--;
  	 }
  
  	public synchronized void setFilesCached(long number)
  	{
  		filesCached = number;
  	}
  
  	 public long getBytesCached()
  	 {
  		  return bytesCached;
  	 }
  
  	 public synchronized void setBytesCached(long number)
  	 {
  		  bytesCached = number;
  	 }
  
  	 public long getBytesFree()
  	 {
  		  return cacheSize - bytesCached;
  	 }
  
  	 public long getHits()
  	 {
  		  return hits;
  	 }
  
  	 public synchronized void increaseHits()
  	 {
  		  hits++;
  	 }
  
  	public synchronized void setHits(long number)
  	{
  		hits = number;
  	}
  
  	 public long getMisses()
  	 {
  		  return misses;
  	 }
  
  	 public synchronized void increaseMisses()
  	 {
  		  misses++;
  	 }
  
  	public synchronized void setMisses(long number)
  	{
  		misses = number;
  	}
  
  	 public double getHitRatio()
  	 {
  		  if ((hits + misses)==0)
  				return 0;
  		  else
  				return 100*hits / (hits + misses);
  	 }
  
  
  	//
  	// Construct a string with all parameters
  	//
  	public synchronized String toString()
  	{
  		int i;
  		String s = "";
  		s += isFatherProxy + separator;
  		  s += fatherProxyHost.equals("") ? "NULL" : fatherProxyHost;
  		  s +=                    separator +
  		  fatherProxyPort       + separator;
  
  		  s += deniedHosts.length + separator;
  		  for (i=0; i<deniedHosts.length; i++)
  				s += deniedHosts[i] + separator;
  
  		  s +=
  		  password              + separator +
  		isCaching             + separator +
  		cacheSize             + separator +
  		  cleanCache            + separator;
  
  		  s += cacheMasks.length + separator;
  		  for (i=0; i<cacheMasks.length; i++)
  				s += cacheMasks[i] + separator;
  
  		  s+= proxyMachineNameAndPort + separator;
  
  		s +=
  		  filesCached           + separator +
  		  bytesCached           + separator +
  		  bytesFree             + separator +
  		  hits                  + separator +
  		  misses                + separator +
  		"\n";
  		return s;
  	}
  
  	//
  	// Set parameters according to a string (that was sent by applet)
  	//
  	public synchronized void parse(String config)
  	{
  		System.out.println("Parsing administrator request...");
  		int size,i;
  		StringTokenizer s = new StringTokenizer(config,separator);
  
  		  isFatherProxy       = s.nextToken().equals("true");
  		System.out.println("Use father proxy = "+isFatherProxy);
  		  fatherProxyHost     = s.nextToken();
  		  if(fatherProxyHost.equals("NULL"))
  			  fatherProxyHost = "";
  		System.out.println("Father proxy name = "+fatherProxyHost);
  
  		  fatherProxyPort     = Integer.parseInt(s.nextToken());
  		System.out.println("Father proxy port = "+fatherProxyPort);
  
  		  size = Integer.parseInt(s.nextToken());
  		  deniedHosts = new String[size];
  		  for (i=0; i<size; i++)
  		{
  				deniedHosts[i] = s.nextToken();
  			System.out.println("Deny access to "+deniedHosts[i]);
  		}
  
  		  password            = s.nextToken();
  		System.out.println("password = "+password);
  		isCaching           = s.nextToken().equals("true");
  		System.out.println("Caching = "+isCaching);
  		cacheSize           = Long.parseLong(s.nextToken());
  		System.out.println("Cache size = "+cacheSize);
  		  cleanCache          = s.nextToken().equals("true");
  		System.out.println("Do cache clean up = "+cleanCache);
  
  		  size = Integer.parseInt(s.nextToken());
  		  cacheMasks = new String[size];
  		  for (i=0; i<size; i++)
  		{
  				cacheMasks[i] = s.nextToken();
  			System.out.println("Don't cache "+cacheMasks[i]);
  		}
  
  		  proxyMachineNameAndPort = s.nextToken();
  
  		if (isAppletContext)
  		{
  			filesCached         = Long.parseLong(s.nextToken());
  			bytesCached         = Long.parseLong(s.nextToken());
  			bytesFree           = Long.parseLong(s.nextToken());
  			hits                = Long.parseLong(s.nextToken());
  			misses              = Long.parseLong(s.nextToken());
  		}
  
  		//
  		// Update bytesFree to reflect the change in cache size.
  		// Note that free bytes can be below min free level now.
  		//
  		bytesFree = cacheSize - bytesCached;
  	}
  }
  
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/Daemon.java
  
  Index: Daemon.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File Daemon.java
  ***
  ***/
  
  import java.net.*;
  import java.io.*;
  
  
  //
  // Class:     Daemon
  // Abstract:  Web daemon thread. creates main socket on port 8080
  //            and listens on it forever. For each client request,
  //            creates proxy thread to handle the request.
  //
  public class Daemon extends Thread
  {
  	//
  	// Member variables
  	//
  	static ServerSocket MainSocket = null;
  	 static Cache cache = null;
  	static Config config;
  	static String adminPath;
  
  	final static int defaultDaemonPort = 8080;
  	final static int maxDaemonPort = 65536;
  
  
  	//
  	// Member methods
  	//
  
  	// Application starts here
  	public static void main(String args[])
  	{
  		int daemonPort;
  
  		// Parse command line
  		switch (args.length)
  		{
  			case 0: daemonPort = defaultDaemonPort;
  					break;
  
  			case 1: try
  					{
  						daemonPort = Integer.parseInt(args[0]);
  					}
  					catch (NumberFormatException e)
  					{
  						System.out.println("Error: Invalid daemon port");
  						return;
  					}
  					if (daemonPort > maxDaemonPort)
  					{
  						System.out.println("Error: Invalid daemon port");
  						return;
  					}
  					break;
  
  			default:System.out.println("Usage: Proxy [daemon port]");
  					return;
  		}
  
  
  
  		try
  		{
  			// Create the Cache Manager and Configuration objects
  			System.out.println("Initializing...");
  			System.out.print("Creating Config Object...");
  			config = new Config();
  			config.setIsAppletContext(false);
  			config.setLocalHost(InetAddress.getLocalHost().getHostName());
  			String tmp = InetAddress.getLocalHost().toString();
  			config.setLocalIP(tmp.substring(tmp.indexOf('/')+1));
  			config.setProxyMachineNameAndPort(InetAddress.getLocalHost().getHostName()+":"+daemonPort);
  			config.setJmxScriptDir("proxy_script");
  			File adminDir = new File("Applet");
  			config.setAdminPath(adminDir.getAbsolutePath());
  			System.out.println("OK");
  
  			System.out.print("Creating Cache Manager...");
  			cache = new Cache(config);
  			System.out.println("OK");
  
  			// Start the admin thread
  			System.out.print("Creating Admin Thread...");
  			Admin adminThd = new Admin(config,cache);
  			adminThd.start();
  			System.out.println(" port " + config.getAdminPort() + " OK");
  
  			// Create main socket
  				System.out.print("Creating Daemon Socket...");
  			MainSocket = new ServerSocket(daemonPort);
  			System.out.println(" port " + daemonPort + " OK");
  
  			if (config.getIsFatherProxy())
  			{
  				System.out.println("Using Father Proxy "+
  					config.getFatherProxyHost()+
  					":"+config.getFatherProxyPort()+" .");
  			}
  			else
  			{
  				System.out.println("Not Using Father Proxy .");
  			}
  			System.out.println("Proxy up and running!");
  
  			// Main loop
  			while (true)
  			{
  				// Listen on main socket
  				Socket ClientSocket = MainSocket.accept();
  
  				// Pass request to new proxy thread
  				Proxy thd = new Proxy(ClientSocket,cache,config);
  				thd.start();
  			}
  
  		}
  
  		catch (Exception e)
  		{}
  
  		finally
  		{
  			try
  			{
  				MainSocket.close();
  			}
  			catch (Exception exc)
  			{
  			}
  		}
  	}
  }
  
  
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/HttpReplyHdr.java
  
  Index: HttpReplyHdr.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File HttpReplyHdr.java
  ***
  ***/
  
  import java.net.*;
  import java.io.*;
  
  //
  // Class:     HttpReplyHdr
  // Abstract:  The headers of the server HTTP reply.
  //
  
  public class HttpReplyHdr
  {
  
  	static String CR="\r\n";
  	static String HTTP_PROTOCOL="HTTP/1.0";
  	static String HTTP_SERVER="Java Proxy Server";
  
  	String lastModified ="";
  	long   contentLength=0;
  	String extraErrorString ="";
  
  /**
   * Sets the last modified date for a header;
   *
   * @param date  A string holding an interner date
   * @return      true
   */
  public boolean setModifiedDate(String date)
  	{
  		lastModified = date;
  		return true;
  	}
  
  /**
   * Adds an extra explanation. This extra information is
   * Added to the http headers failure explanation.
   *
   * @param str  Description to add.
   * @return     true.
   */
  public boolean addErrorDescription(String str)
  	{
  		extraErrorString = str;
  		return true;
  	}
  
  /**
   * Forms a http ok reply header
   *
   * @param ContentType The mime-type of the content
   * @return            A string with the header in it
   */
  public String formOk(String ContentType,long  ContentLength)
  	{
  
  		 contentLength = ContentLength;
  
  		 String out =new String();
  
  		 out += HTTP_PROTOCOL + " 200 Ok" + CR;
  		 out += "Server: " + HTTP_SERVER  + CR;
  		 out += "MIME-version: 1.0"       + CR;
  
  		 if (0 < ContentType.length())
  			  out += "Content-type: " + ContentType + CR;
  		 else
  			  out += "Content-Type: text/html" + CR;
  
  		 if (0 != contentLength)
  			  out += "Content-Length: " + Long.toString(contentLength) + CR;
  
  		 if (0 < lastModified.length())
  			  out +="Last-Modified: " + lastModified + CR;
  
  		 out +=CR;
  
  		 return out;
  	}
  
  
  /**
   * private! builds an http document describing a headers reason.
   *
   * @param Error        Error name.
   * @param Description  Errors description.
   * @return             A string with the HTML description body
   */
  private String formErrorBody(String Error,String Description)
  	{
  	String out;
  	//Generate Error Body
  	out  ="<HTML><HEAD><TITLE>";
  	out += Error ;
  	out +="</TITLE></HEAD>";
  	out +="<BODY><H2>" + Error +"</H2>\n";
  	out +="</P></H3>";
  	out += Description;
  	out +="</BODY></HTML>";
  	return out;
  	}
  
  
  
  /**
   * builds an http document describing an error.
   *
   * @param Error        Error name.
   * @param Description  Errors description.
   * @return             A string with the HTML description body
   */
  private String formError(String Error, String Description)
  	{
  	/* A HTTP RESPONCE HEADER LOOKS ALOT LIKE:
  	 *
  	 * HTTP/1.0 200 OK
  	 * Date: Wednesday, 02-Feb-94 23:04:12 GMT
  	 * Server: NCSA/1.1
  	 * MIME-version: 1.0
  	 * Last-modified: Monday, 15-Nov-93 23:33:16 GMT
  	 * Content-type: text/html
  	 * Content-length: 2345
  	 * \r\n
  	 */
  
  	String body=formErrorBody(Error,Description);
  	String header =new String();
  
  	header +=HTTP_PROTOCOL +" " + Error + CR;
  	header +="Server: " + HTTP_SERVER   + CR;
  	header +="MIME-version: 1.0"        + CR;
  	header +="Content-type: text/html"  + CR;
  
  	if (0 < lastModified.length())
  		 header +="Last-Modified: " + lastModified +CR;
  
  	header +="Content-Length: " + String.valueOf(body.length())+ CR;
  
  	header += CR;
  	header += body;
  
  	return header;
  	}
  
  
  /**
   * Indicates a new file was created.
   *
   * @return    The header in a string;
   */
  public String formCreated()
  	{
  	return formError("201 Created","Object was created");
  	}
  
  /**
   * Indicates the document was accepted.
   *
   * @return    The header in a string;
   */
  public String formAccepted()
  	{
  	return formError("202 Accepted","Object checked in");
  	}
  
  /**
   * Indicates only a partial responce was sent.
   *
   * @return    The header in a string;
   */
  public String  formPartial()
  	{
  	return formError("203 Partial","Only partail document available");
  	}
  
  /**
   * Indicates a requested URL has moved to a new address or name.
   *
   * @return    The header in a string;
   */
  public String formMoved()
  	{
  	//300 codes tell client to do actions
  	return formError("301 Moved","File has moved");
  	}
  
  /**
   * Never seen this used.
   *
   * @return    The header in a string;
   */
  public String formFound()
  	{
  	return formError("302 Found","Object was found");
  	}
  
  /**
   * The requested method is not implemented by the server.
   *
   * @return    The header in a string;
   */
  public String formMethod()
  	{
  	return formError("303 Method unseported","Method unseported");
  	}
  
  /**
   * Indicates remote copy of the requested object is current.
   *
   * @return    The header in a string;
   */
  public String formNotModified()
  	{
  	return formError("304 Not modified","Use local copy");
  	}
  
  /**
   * Client not otherized for the request.
   *
   * @return    The header in a string;
   */
  public String formUnautorized()
  	{
  	return formError("401 Unathorized","Unathorized use of this service");
  	}
  
  /**
   * Payment is required for service.
   *
   * @return    The header in a string;
   */
  public String formPaymentNeeded()
  	{
  	return formError("402 Payment required","Payment is required");
  	}
  
  /**
   * Client if forbidden to get the request service.
   *
   * @return    The header in a string;
   */
  public String formForbidden()
  	{
  	return formError("403 Forbidden","You need permission for this service");
  	}
  
  /**
   * The requested object was not found.
   *
   * @return    The header in a string;
   */
  public String formNotFound()
  	{
  	return formError("404 Not_found","Requested object was not found");
  	}
  
  /**
   * The server had a problem and could not fulfill the request.
   *
   * @return    The header in a string;
   */
  public String formInternalError()
  	{
  	return formError("500 Internal server error","Server broke");
  	}
  
  /**
   * Server does not do the requested feature.
   *
   * @return    The header in a string;
   */
  public String formNotImplemented()
  	{
  	return formError("501 Method not implemented","Service not implemented, programer was lazy");
  	}
  
  /**
   * Server is overloaded, client should try again latter.
   *
   * @return    The header in a string;
   */
  public String formOverloaded()
  	{
  	return formError("502 Server overloaded","Try again latter");
  	}
  
  /**
   * Indicates the request took to long.
   *
   * @return    The header in a string;
   */
  public String formTimeout()
  	{
  	return formError("503 Gateway timeout","The connection timed out");
  	}
  
  /**
   * Indicates the client's proxies could not locate a server.
   *
   * @return    The header in a string;
   */
  public String formServerNotFound()
  	{
  	return formError("503 Gateway timeout","The requested server was not found");
  	}
  
  /**
   * Indicates the client is not allowed to access the object.
   *
   * @return    The header in a string;
   */
  public String formNotAllowed()
  	{
  	return formError("403 Access Denied","Access is not allowed");
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/HttpRequestHdr.java
  
  Index: HttpRequestHdr.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  /******************************************************************
  *** File HttpRequestHdr.java
  ***
  ***/
  
  import java.io.InputStream;
  import java.io.DataInputStream;
  import java.util.StringTokenizer;
  
  //
  // Class:     HttpRequestHdr
  // Abstract:  The headers of the client HTTP request.
  //
  
  public class HttpRequestHdr
  {
  
  	/**
  	 * Http Request method. Such as get or post.
  	 */
  	public  String method = new String();
  
  	/**
  	 * The requested url. The universal resource locator that
  	 * hopefully uniquely describes the object or service the
  	 * client is requesting.
  	 */
  	public String url   = new String();
  
  	/**
  	 * Version of http being used. Such as HTTP/1.0
  	 */
  	public String version           = new String();
  
  	/**
  	 * The client's browser's name.
  	 */
  	public String userAgent         = new String();
  
  	/**
  	 * The requesting documents that contained the url link.
  	 */
  	public String referer           = new String();
  
  	/**
  	 * A internet address date of the remote copy.
  	 */
  	public String ifModifiedSince   = new String();
  
  	/**
  	 * A list of mime types the client can accept.
  	 */
  	public String accept            = new String();
  
  	/**
  	 * The clients authorization. Don't belive it.
  	 */
  
  	public String authorization     = new String();
  	/**
  	 * The type of content following the request header.
  	 * Normally there is no content and this is blank, however
  	 * the post method usually does have a content and a content
  	 * length.
  	 */
  	public String contentType       = new String();
  	/**
  	 * The length of the content following the header. Usually
  	 * blank.
  	 */
  	public int    contentLength     = -1;
  	/**
  	 * The content length of a remote copy of the requested object.
  	 */
  	public int    oldContentLength  = -1;
  	/**
  	 * Anything in the header that was unrecognized by this class.
  	 */
  	public String unrecognized      = new String();
  	/**
  	 * Indicates that no cached versions of the requested object are
  	 * to be sent. Usually used to tell proxy not to send a cached copy.
  	 * This may also effect servers that are front end for data bases.
  	 */
  	public boolean pragmaNoCache    = false;
  
  	static String CR ="\r\n";
  
  
  /**
   * Parses a http header from a stream.
   *
   * @param in  The stream to parse.
   * @return    true if parsing sucsessfull.
   */
  public boolean parse(InputStream In)
  	{
  		 String CR ="\r\n";
  
  		 /*
  		  * Read by lines
  		  */
  		 DataInputStream lines;
  		 StringTokenizer tz;
  		 try
  		{
  			  lines = new DataInputStream(In);
  			  tz = new StringTokenizer(lines.readLine());
  		 }
  		catch (Exception e)
  		{
  			  return false;
  		 }
  
  		 /*
  		  * HTTP COMMAND LINE < <METHOD==get> <URL> <HTTP_VERSION> >
  		  */
  		 method = getToken(tz).toUpperCase();
  		 url    = getToken(tz);
  		 version= getToken(tz);
  
  		 while (true)
  		{
  			  try
  			{
  					tz = new StringTokenizer(lines.readLine());
  			  }
  			catch (Exception e)
  			{
  					return false;
  			  }
  			  String Token = getToken(tz);
  
  			  // look for termination of HTTP command
  			  if (0 == Token.length())
  					break;
  
  			  if (Token.equalsIgnoreCase("USER-AGENT:")) {
  					// line =<User-Agent: <Agent Description>>
  					userAgent = getRemainder(tz);
  			  } else if (Token.equalsIgnoreCase("ACCEPT:")) {
  					// line=<Accept: <Type>/<Form>
  					// examp: Accept image/jpeg
  					accept += " " + getRemainder(tz);
  
  			  } else if (Token.equalsIgnoreCase("REFERER:")) {
  					// line =<Referer: <URL>>
  					referer = getRemainder(tz);
  
  			  } else if (Token.equalsIgnoreCase("PRAGMA:")) {
  					// Pragma: <no-cache>
  					Token = getToken(tz);
  
  					if (Token.equalsIgnoreCase("NO-CACHE"))
  						 pragmaNoCache = true;
  					else
  						 unrecognized += "Pragma:" + Token + " "
  							  +getRemainder(tz) +"\n";
  			  } else if (Token.equalsIgnoreCase("AUTHORIZATION:")) {
  					// Authenticate: Basic UUENCODED
  					authorization=  getRemainder(tz);
  
  			  } else if (Token.equalsIgnoreCase("IF-MODIFIED-SINCE:")) {
  					// line =<If-Modified-Since: <http date>
  					// *** Conditional GET replaces HEAD method ***
  					String str = getRemainder(tz);
  				  int index = str.indexOf(";");
  				  if (index == -1) {
  						 ifModifiedSince  =str;
  					} else {
  						 ifModifiedSince  =str.substring(0,index);
  
  						index = str.indexOf("=");
  						if (index != -1) {
  							 str = str.substring(index+1);
  							 oldContentLength =Integer.parseInt(str);
  						}
  				  }
  			  } else if (Token.equalsIgnoreCase("CONTENT-LENGTH:")) {
  					Token = getToken(tz);
  					contentLength =Integer.parseInt(Token);
  			  } else if (Token.equalsIgnoreCase("CONTENT-TYPE:")) {
  					contentType = getRemainder(tz);
  			  } else {
  					unrecognized += Token + " " + getRemainder(tz) + CR;
  			  }
  		 }
  		 return true;
  	}
  
  	/*
  	 * Rebuilds the header in a string
  	 * @returns      The header in a string.
  	 */
  	public String toString(boolean sendUnknowen) {
  		 String Request;
  
  		 if (0 == method.length())
  				method = "GET";
  
  		 Request = method +" "+ url + " HTTP/1.0" + CR;
  
  		 if (0 < userAgent.length())
  			  Request +="User-Agent:" + userAgent + CR;
  
  		 if (0 < referer.length())
  			  Request+= "Referer:"+ referer  + CR;
  
  		 if (pragmaNoCache)
  			  Request+= "Pragma: no-cache" + CR;
  
  		 if (0 < ifModifiedSince.length())
  			  Request+= "If-Modified-Since: " + ifModifiedSince + CR;
  
  		 // ACCEPT TYPES //
  		 if (0 < accept.length())
  			  Request += "Accept: " + accept + CR;
  		 else
  			  Request += "Accept: */"+"* \r\n";
  
  		 if (0 < contentType.length())
  			  Request += "Content-Type: " + contentType   + CR;
  
  		 if (0 < contentLength)
  			  Request += "Content-Length: " + contentLength + CR;
  
  
  		 if (0 != authorization.length())
  			  Request += "Authorization: " + authorization + CR;
  
  		 if (sendUnknowen) {
  			  if (0 != unrecognized.length())
  					Request += unrecognized;
  		 }
  
  		 Request += CR;
  
  		 return Request;
  	}
  
  
  	/**
  	 * (Re)builds the header in a string.
  	 *
  	 * @returns      The header in a string.
  	 */
  	public String toString() {
  		 return toString(true);
  	}
  
  	/**
  	 *  Returns the next token in a string
  	 *
  	 * @param   tk String that is partially tokenized.
  	 * @returns The remainder
  	 */
  	String  getToken(StringTokenizer tk){
  		 String str ="";
  		 if  (tk.hasMoreTokens())
  			  str =tk.nextToken();
  		 return str;
  	}
  
  	/**
  	 *  Returns the remainder of a tokenized string
  	 *
  	 * @param   tk String that is partially tokenized.
  	 * @returns The remainder
  	 */
  	String  getRemainder(StringTokenizer tk){
  		 String str ="";
  		 if  (tk.hasMoreTokens())
  			  str =tk.nextToken();
  		 while (tk.hasMoreTokens()){
  			  str +=" " + tk.nextToken();
  		 }
  		 return str;
  	}
  
  		//
  	// Parsing Methods
  	//
  
  	 /**
  	  * Find the //server.name from an url.
  	  *
  	  * @return Servers internet name
  	  */
  	 public String serverName()
  	{
  		  // chop to "server.name:x/thing"
  		  String str = url;
  		  int i = str.indexOf("//");
  		  if (i< 0) return "";
  		  str = str.substring(i+2);
  
  		  // chop to  server.name:xx
  		  i = str.indexOf("/");
  		  if (0 < i) str = str.substring(0,i);
  
  		  // chop to server.name
  		  i = str.indexOf(":");
  		  if (0 < i) str = str.substring(0,i);
  
  		  return str;
  	 }
  
  	 /**
  	  * Find the :PORT form http://server.ect:PORT/some/file.xxx
  	  *
  	  * @return Servers internet name
  	  */
  	 public int serverPort()
  	{
  		  String str = url;
  		  // chop to "server.name:x/thing"
  		  int i = str.indexOf("//");
  		  if (i< 0) return 80;
  		  str = str.substring(i+2);
  
  		  // chop to  server.name:xx
  		  i = str.indexOf("/");
  		  if (0 < i) str = str.substring(0,i);
  
  		  // chop XX
  		  i = str.indexOf(":");
  		  if (0 < i)
  		{
  				return Integer.parseInt(str.substring(i+1).trim());
  		  }
  
  		  return 80;
  	 }
  
  	 /**
  	  * Find the /some/file.xxxx form http://server.ect:PORT/some/file.xxx
  	  *
  	  * @return the deproxied url
  	  */
  	 public String serverUrl()
  	{
  		  String str = url;
  		  int i = str.indexOf("//");
  		  if (i< 0) return str;
  
  		  str = str.substring(i+2);
  		  i = str.indexOf("/");
  		  if (i< 0) return str;
  
  		  return str.substring(i);
  	 }
  
  }
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/proxy/Proxy.java
  
  Index: Proxy.java
  ===================================================================
  package org.apache.jmeter.protocol.http.proxy;
  
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import org.apache.jmeter.protocol.http.config.UrlConfig;
  import org.apache.jmeter.save.xml.TagHandler;
  
  //
  // Class:     Proxy
  // Abstract:  Thread to handle one client request. get the requested
  //            object from the web server or from the cache, and delivers
  //            the bits to client.
  //
  /**
   *  Description of the Class
   *
   *@author     mike
   *@created    June 8, 2001
   */
  public class Proxy extends Thread
  {
  	//
  	// Member variables
  	//
  	Socket ClientSocket = null;
  	// Socket to client
  	Socket SrvrSocket = null;
  	// Socket to web server
  	Cache cache = null;
  	// Static cache manager object
  	String localHostName = null;
  	// Local machine name
  	String localHostIP = null;
  	// Local machine IP address
  	String adminPath = null;
  	// Path of admin applet
  	Config config = null;
  	// Config object
  	UrlConfig urlConfig = null;
  	// UrlConfig object for saving test cases
  
  
  	//
  	// Public member methods
  	//
  
  	//
  	// Constructor
  	//
  	Proxy(Socket clientSocket, Cache CacheManager, Config configObject)
  	{
  		//
  		// Initialize member variables
  		//
  		config = configObject;
  		ClientSocket = clientSocket;
  		cache = CacheManager;
  		localHostName = config.getLocalHost();
  		localHostIP = config.getLocalIP();
  		adminPath = config.getAdminPath();
  	}
  
  
  	//
  	// run - Main work is done here:
  	//
  	/**
  	 *  Main processing method for the Proxy object
  	 */
  	public void run()
  	{
  		String serverName = "";
  		URL url;
  
  		byte line[];
  		HttpRequestHdr request = new HttpRequestHdr();
  		HttpReplyHdr reply = new HttpReplyHdr();
  		FileInputStream fileInputStream = null;
  		FileOutputStream fileOutputStream = null;
  		boolean TakenFromCache = false;
  		boolean isCachable = false;
  
  		try
  		{
  			//
  			// Read HTTP Request from client
  			//
  			request.parse(ClientSocket.getInputStream());
  			createUrlConfig(request);
  			config.increaseFilesCached();
  			url = new URL(request.url);
  			System.out.println("Request = " + url);
  
  			//
  			// Send Web page with applet to administrator
  			//
  			if (url.getFile().equalsIgnoreCase("/admin") &&
  					(url.getHost().equalsIgnoreCase(localHostName) ||
  					url.getHost().equalsIgnoreCase(localHostIP)))
  			{
  				sendAppletWebPage();
  				return;
  			}
  
  			//
  			// Send Applet Files to administrator
  			//
  			if ((url.getHost().equalsIgnoreCase(localHostName) ||
  					url.getHost().equalsIgnoreCase(localHostIP)))
  			{
  				sendAppletClass(url.getFile());
  				return;
  			}
  
  			//
  			// Check if accessing the URL is allowed by administrator
  			//
  			String[] denied = config.getDeniedHosts();
  			for (int i = 0; i < denied.length; i++)
  			{
  				if (url.toString().indexOf(denied[i]) != -1)
  				{
  					System.out.println("Access not allowed...");
  					DataOutputStream out =
  							new DataOutputStream(ClientSocket.getOutputStream());
  					out.writeBytes(reply.formNotAllowed());
  					out.flush();
  					ClientSocket.close();
  					return;
  				}
  			}
  
  			serverName = url.getHost();
  			System.out.println("Miss! Forwarding to server " +
  					serverName + "...");
  			config.increaseMisses();
  			SrvrSocket = new Socket(request.serverName(),
  					request.serverPort());
  			request.url = request.serverUrl();
  
  			DataOutputStream srvOut =
  					new DataOutputStream(SrvrSocket.getOutputStream());
  
  			//
  			// Send the url to web server (or father proxy)
  			//
  			srvOut.writeBytes(request.toString(false));
  			srvOut.flush();
  
  			//
  			// Send data to server (needed for post method)
  			//
  			StringBuffer buff = new StringBuffer();
  			int readValue;
  			for (int i = 0; i < request.contentLength; i++)
  			{
  				readValue = ClientSocket.getInputStream().read();
  				buff.append((char)readValue);
  				SrvrSocket.getOutputStream().write(readValue);
  			}
  			SrvrSocket.getOutputStream().flush();
  			urlConfig.parseArguments(buff.toString());
  			saveUrlConfig();
  
  			// Third, check reply headers (we must read first
  			//         line of headers for that).
  			DataInputStream Din =
  					new DataInputStream(SrvrSocket.getInputStream());
  			DataOutputStream Dout =
  					new DataOutputStream(ClientSocket.getOutputStream());
  			String str = Din.readLine();
  			StringTokenizer s = new StringTokenizer(str);
  			String retCode = s.nextToken();
  			// first token is HTTP protocol
  			retCode = s.nextToken();
  			// second is return code
  
  			//
  			// First line was read - send it to client and cache it
  			//
  			String tempStr = new String(str + "\r\n");
  			Dout.writeBytes(tempStr);
  
  			//
  			// Read next lines in reply header, send them to
  			// client and cache them
  			//
  			if (str.length() > 0)
  			{
  				while (true)
  				{
  					str = Din.readLine();
  					tempStr = new String(str + "\r\n");
  
  					// Send bits to client
  					Dout.writeBytes(tempStr);
  
  					if (str.length() <= 0)
  					{
  						break;
  					}
  				}
  			}
  			Dout.flush();
  
  			//
  			// With the HTTP reply body do:
  			//   (1) Send it to client.
  			//   (2) Cache it.
  			//
  			InputStream in = SrvrSocket.getInputStream();
  			OutputStream out = ClientSocket.getOutputStream();
  
  			byte data[] = new byte[2000];
  			int count;
  			while ((count = in.read(data)) > 0)
  			{
  				// Send bits to client
  				out.write(data, 0, count);
  			}
  			out.flush();
  		}
  
  		catch (UnknownHostException uhe)
  		{
  			//
  			// Requested Server could not be located
  			//
  			System.out.println("Server Not Found.");
  
  			try
  			{
  				// Notify client that server not found
  				DataOutputStream out =
  						new DataOutputStream(ClientSocket.getOutputStream());
  				out.writeBytes(reply.formServerNotFound());
  				out.flush();
  			}
  			catch (Exception uhe2)
  			{
  			}
  		}
  
  		catch (Exception e)
  		{
  			e.printStackTrace();
  			try
  			{
  				if (TakenFromCache)
  				{
  					fileInputStream.close();
  				}
  				else if (isCachable)
  				{
  					fileOutputStream.close();
  				}
  
  				// Notify client that internal error accured in proxy
  				DataOutputStream out =
  						new DataOutputStream(ClientSocket.getOutputStream());
  				out.writeBytes(reply.formTimeout());
  				out.flush();
  
  			}
  			catch (Exception uhe2)
  			{
  			}
  		}
  
  		finally
  		{
  			try
  			{
  				ClientSocket.getOutputStream().flush();
  				ClientSocket.close();
  			}
  			catch (Exception e)
  			{
  			}
  		}
  	}
  
  
  	//
  	// Private methods
  	//
  
  	//
  	// Send to administrator web page containing reference to applet
  	//
  	private void sendAppletWebPage()
  	{
  		System.out.println("Sending the applet...");
  		String page = "";
  		try
  		{
  			File appletHtmlPage = new File(config.getAdminPath() +
  					File.separator + "Admin.html");
  			DataInputStream in = new DataInputStream(new FileInputStream(appletHtmlPage));
  
  			String s = null;
  
  			while ((s = in.readLine()) != null)
  			{
  				page += s;
  			}
  
  			page = page.substring(0, page.indexOf("PORT")) +
  					config.getAdminPort() +
  					page.substring(page.indexOf("PORT") + 4);
  
  			in.close();
  			DataOutputStream out = new DataOutputStream(ClientSocket.getOutputStream());
  			out.writeBytes(page);
  			out.flush();
  			out.close();
  		}
  		catch (Exception e)
  		{
  			System.out.println("Error: can't open applet html page");
  		}
  
  	}
  
  
  	//
  	// Send the applet to administrator
  	//
  	private void sendAppletClass(String className)
  	{
  		try
  		{
  			byte data[] = new byte[2000];
  			int count;
  			HttpReplyHdr reply = new HttpReplyHdr();
  			File appletFile = new File(adminPath + File.separatorChar + className);
  			long length = appletFile.length();
  
  			FileInputStream in = new FileInputStream(appletFile);
  			DataOutputStream out = new DataOutputStream(ClientSocket.getOutputStream());
  
  			out.writeBytes(reply.formOk("application/octet-stream", length));
  
  			while (-1 < (count = in.read(data)))
  			{
  				out.write(data, 0, count);
  			}
  			out.flush();
  			in.close();
  			out.close();
  		}
  		catch (Exception e)
  		{
  		}
  	}
  
  	private void createUrlConfig(HttpRequestHdr request)
  	{
  		System.out.println("extra stuff = " + request.unrecognized);
  		System.out.println("Everything = " + request.toString(false));
  		urlConfig = new UrlConfig();
  		urlConfig.setDomain(request.serverName());
  		urlConfig.setMethod(request.method);
  		urlConfig.setPath(request.serverUrl());
  		urlConfig.setName(urlConfig.getPath());
  		urlConfig.setProtocol(request.url.substring(0, request.url.indexOf(":")));
  		urlConfig.setPort(request.serverPort());
  
  	}
  
  	private void saveUrlConfig()
  	{
  		try
  		{
  			String name;
  			int index = urlConfig.getName().lastIndexOf("/");
  			if (index > -1)
  			{
  				name = urlConfig.getName().substring(index + 1);
  			}
  			else
  			{
  				name = urlConfig.getName();
  			}
  			FileWriter out = new FileWriter(System.getProperty("user.dir") +
  					File.separator + config.getJmxScriptDir() + File.separator + name +
  					"_" + config.getFilesCached() + ".jmx");
  			TagHandler handler = (TagHandler) urlConfig.getTagHandlerClass().newInstance();
  			handler.startSave(out);
  			handler.save(urlConfig, out);
  			out.close();
  		}
  		catch (Exception e)
  		{
  			e.printStackTrace();
  		}
  	}
  }
  
  
  
  1.12      +20 -2     jakarta-jmeter/src/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java
  
  Index: HTTPSampler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- HTTPSampler.java	2001/06/07 23:38:47	1.11
  +++ HTTPSampler.java	2001/06/14 00:28:21	1.12
  @@ -72,8 +72,8 @@
    *  HTTP requests, including cookies and authentication.
    *
    *@author     Michael Stover
  - *@created    $Date: 2001/06/07 23:38:47 $
  - *@version    $Revision: 1.11 $
  + *@created    $Date: 2001/06/14 00:28:21 $
  + *@version    $Revision: 1.12 $
    ***********************************************************/
   public class HTTPSampler implements Sampler
   {
  @@ -169,6 +169,23 @@
   		}
   	}
   
  +	private void setConnectionHeaders(HttpURLConnection conn, URL u, HeaderManager headerManager)
  +	{
  +		if(headerManager != null)
  +		{
  +			Collection headers = headerManager.getHeaders();
  +			if(headers != null)
  +			{
  +				Iterator i = headers.iterator();
  +				while(i.hasNext())
  +				{
  +					Header header = (Header)i.next();
  +					conn.setRequestProperty(header.getName(),header.getValue());
  +				}
  +			}
  +		}
  +	}
  +
   	private void setConnectionAuthorization(HttpURLConnection conn, URL u, AuthManager authManager)
   	{
   		if (authManager != null)
  @@ -241,6 +258,7 @@
   			conn = (HttpURLConnection)u.openConnection();
   			conn.setFollowRedirects(false);
   			conn.setRequestMethod((String)url.getProperty(UrlConfig.METHOD));
  +			setConnectionHeaders(conn,u,(HeaderManager)e.getConfigElement(HeaderManager.class));
   			setConnectionCookie(conn, u, (CookieManager)e.getConfigElement(CookieManager.class));
   			setConnectionAuthorization(conn, u, (AuthManager)e.getConfigElement(AuthManager.class));
   			// if POSTing data, write data to output stream
  
  
  
  1.1                  jakarta-jmeter/src/org/apache/jmeter/protocol/http/save/HeaderManagerHandler.java
  
  Index: HeaderManagerHandler.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jmeter.protocol.http.save;
  
  import org.xml.sax.Attributes;
  import java.util.*;
  
  import org.apache.jmeter.save.Saveable;
  import java.io.Writer;
  import org.apache.jmeter.save.xml.*;
  import org.apache.jmeter.save.handlers.JMeterHandler;
  
  import org.apache.jmeter.protocol.http.control.*;
  
  /**
   * Title:
   * Description:
   * Copyright:    Copyright (c) 2001
   * Company:
   * @author Giacomo Pati
   * @version 1.0
   */
  
  public class HeaderManagerHandler extends TagHandler
  {
  
  	private HeaderManager headerManager;
  
  	public HeaderManagerHandler()
  	{
  	}
  
  	public void save(Saveable cm, Writer out) throws java.io.IOException
  	{
  		HeaderManager headers = (HeaderManager)cm;
  		out.write("<HeaderManager name=\"");
  		out.write(JMeterHandler.convertToXML(headers.getName()));
  		out.write("\">\n");
  		JMeterHandler.writeObjects(headers.getHeaders(),out);
  		out.write("</HeaderManager>\n");
  	}
  
  	public void setAtts(Attributes atts) throws java.lang.Exception
  	{
  		headerManager = new HeaderManager();
  		headerManager.setName(atts.getValue("name"));
  	}
  
  	public String getPrimaryTagName()
  	{
  		return "HeaderManager";
  	}
  
  	public void HeaderManagerTagEnd()
  	{
  		List headers = xmlParent.takeChildObjects(this);
  		Iterator iter = headers.iterator();
  		while (iter.hasNext())
  		{
  			headerManager.add((Header)((TagHandler)iter.next()).getModel());
  		}
  	}
  
  	public Object getModel()
  	{
  		return headerManager;
  	}
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org