/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.scripting.http; import java.net.URL; import java.util.Set; import com.slamd.http.HTTPRequest; import com.slamd.scripting.engine.Argument; import com.slamd.scripting.engine.Method; import com.slamd.scripting.engine.ScriptException; import com.slamd.scripting.engine.Variable; import com.slamd.scripting.general.BooleanVariable; import com.slamd.scripting.general.StringArrayVariable; import com.slamd.scripting.general.StringVariable; /** * This class defines a variable that can be used to encapsulate a request to * send to an HTTP server. An HTTP request variable offers the following * methods: * * <UL> * <LI>addParameter(string name, string value) -- Adds a parameter with the * specified name and value to this request. This method does not return * a value.</LI> * <LI>addParameter(string name, stringarray values) -- Adds a parameter with * the specified name and set of values to this request. This method does * not return a value.</LI> * <LI>assign(string url) -- Initializes this request using the provided URL. * This method returns a boolean value that indicates whether the * assignment was completed successfully.</LI> * <LI>assign(string method, string url) -- Initializes this request using the * provided method (either GET or POST) and URL. This method returns a * boolean value that indicates whether the assignment was completed * successfully.</LI> * <LI>clearHeaders() -- Clears all header information associated with this * request. This method does not return a value.</LI> * <LI>getHeader(string name) -- Returns a string containing value of the * header with the specified name.</LI> * <LI>getHeaderNames() -- Returns a string array containing the names of all * the headers associated with this request.</LI> * <LI>getMethod() -- Returns a string value containing the method used for * this request.</LI> * <LI>getParameter(string name) -- Returns a string containing the value of * the specified parameter.</LI> * <LI>getParameterNames() -- Returns a string array containing the names of * all parameters associated with this request.</LI> * <LI>getParameterValues(string name) -- Returns a string array containing * the set of values for the specified parameter.</LI> * <LI>getURL() -- Returns a string containing the URL for the request.</LI> * <LI>removeAllParameters() -- Removes all parameters from this request. * This method does not return a value.</LI> * <LI>removeHeader(string name) -- Removes the header with the specified name * from this request. This method does not return a value.</LI> * <LI>removeParameter(string name) -- Removes all values for the parameter * with the specified name from this request. This method does not return * a value.</LI> * <LI>removeParameter(string name, string value) -- Removes the parameter * with the specified name and value from this request. This method does * not return a value.</LI> * <LI>replaceParameter(string name, string value) -- Replaces the set of * values for the parameter with the specified name with the provided * value. This method does not return a value.</LI> * <LI>replaceParameter(string name, stringarray values) -- Replaces the set * of values for the parameter with the specified name with the given set * of values. This method does not return a value.</LI> * <LI>setHeader(string name, string value) -- Sets the value of the header * with the given name to the provided value. This method does not return * a value.</LI> * </UL> * * * @author Neil A. Wilson */ public class HTTPRequestVariable extends Variable { /** * The name that will be used for the data type of HTTP request variables. */ public static final String HTTP_REQUEST_VARIABLE_TYPE = "httprequest"; /** * The name of the method that can be used to add a parameter value or set of * values to this request. */ public static final String ADD_PARAMETER_METHOD_NAME = "addparameter"; /** * The method number for the first "addParameter" method. */ public static final int ADD_PARAMETER_1_METHOD_NUMBER = 0; /** * The method number for the second "addParameter" method. */ public static final int ADD_PARAMETER_2_METHOD_NUMBER = 1; /** * The name of the method that can be used to initialize this request. */ public static final String ASSIGN_METHOD_NAME = "assign"; /** * The method number for the first "assign" method. */ public static final int ASSIGN_1_METHOD_NUMBER = 2; /** * The method number for the second "assign" method. */ public static final int ASSIGN_2_METHOD_NUMBER = 3; /** * The name of the method that can be used to remove all header information * from this request. */ public static final String CLEAR_HEADERS_METHOD_NAME = "clearheaders"; /** * The method number for the "clearHeaders" method. */ public static final int CLEAR_HEADERS_METHOD_NUMBER = 4; /** * The name of the method that can be used to retrieve the value of a * specified header from this request. */ public static final String GET_HEADER_METHOD_NAME = "getheader"; /** * The method number for the "getHeader" method. */ public static final int GET_HEADER_METHOD_NUMBER = 5; /** * The name of the method that can be used to retrieve the names of the * headers associated with this request. */ public static final String GET_HEADER_NAMES_METHOD_NAME = "getheadernames"; /** * The method number for the "getHeaderNames" method. */ public static final int GET_HEADER_NAMES_METHOD_NUMBER = 6; /** * The name of the method that can be used to retrieve the request method for * this request. */ public static final String GET_METHOD_METHOD_NAME = "getmethod"; /** * The method number for the "getMethod" method. */ public static final int GET_METHOD_METHOD_NUMBER = 7; /** * The name of the method that can be used to retrieve the value of the * specified parameter from this request. */ public static final String GET_PARAMETER_METHOD_NAME = "getparameter"; /** * The method number for the "getParameter" method. */ public static final int GET_PARAMETER_METHOD_NUMBER = 8; /** * The name of the method that can be used to retrieve the names of the * parameters associated with this request. */ public static final String GET_PARAMETER_NAMES_METHOD_NAME = "getparameternames"; /** * The method number for the "getParameterNames" method. */ public static final int GET_PARAMETER_NAMES_METHOD_NUMBER = 9; /** * The name of the method that can be used to retrieve the set of values for * the specified parameter from this request. */ public static final String GET_PARAMETER_VALUES_METHOD_NAME = "getparametervalues"; /** * The method number for the "getParameterValues" method. */ public static final int GET_PARAMETER_VALUES_METHOD_NUMBER = 10; /** * The name of the method that can be used to retrieve the URL associated with * this request. */ public static final String GET_URL_METHOD_NAME = "geturl"; /** * The method number for the "getURL" method. */ public static final int GET_URL_METHOD_NUMBER = 11; /** * The name of the method that can be used to remove all parameter information * associated with this request. */ public static final String REMOVE_ALL_PARAMETERS_METHOD_NAME = "removeallparameters"; /** * The method number for the "removeAllParameters" method. */ public static final int REMOVE_ALL_PARAMETERS_METHOD_NUMBER = 12; /** * The name of the method that can be used to remove the specified header from * this request. */ public static final String REMOVE_HEADER_METHOD_NAME = "removeheader"; /** * The method number for the "removeHeader" method. */ public static final int REMOVE_HEADER_METHOD_NUMBER = 13; /** * The name of the method that can be used to remove the specified parameter * or parameter value from this request. */ public static final String REMOVE_PARAMETER_METHOD_NAME = "removeparameter"; /** * The method number for the first "removeParameter" method. */ public static final int REMOVE_PARAMETER_1_METHOD_NUMBER = 14; /** * The method number for the second "removeParameter" method. */ public static final int REMOVE_PARAMETER_2_METHOD_NUMBER = 15; /** * The name of the method that can be used to replace the set of values for * the specified parameter in this request. */ public static final String REPLACE_PARAMETER_METHOD_NAME = "replaceparameter"; /** * The method number for the first "replaceParameter" method. */ public static final int REPLACE_PARAMETER_1_METHOD_NUMBER = 16; /** * The method number for the second "replaceParameter" method. */ public static final int REPLACE_PARAMETER_2_METHOD_NUMBER = 17; /** * The name of the method that can be used to set the value of a header for * this request. */ public static final String SET_HEADER_METHOD_NAME = "setheader"; /** * The method number for the "setHeader" method. */ public static final int SET_HEADER_METHOD_NUMBER = 18; /** * The set of methods associated with HTTP request variables. */ public static final Method[] HTTP_REQUEST_VARIABLE_METHODS = new Method[] { new Method(ADD_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringVariable.STRING_VARIABLE_TYPE }, null), new Method(ADD_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringArrayVariable.STRING_ARRAY_VARIABLE_TYPE }, null), new Method(ASSIGN_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, BooleanVariable.BOOLEAN_VARIABLE_TYPE), new Method(ASSIGN_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringVariable.STRING_VARIABLE_TYPE }, BooleanVariable.BOOLEAN_VARIABLE_TYPE), new Method(CLEAR_HEADERS_METHOD_NAME, new String[0], null), new Method(GET_HEADER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, StringVariable.STRING_VARIABLE_TYPE), new Method(GET_HEADER_NAMES_METHOD_NAME, new String[0], StringArrayVariable.STRING_ARRAY_VARIABLE_TYPE), new Method(GET_METHOD_METHOD_NAME, new String[0], StringVariable.STRING_VARIABLE_TYPE), new Method(GET_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, StringVariable.STRING_VARIABLE_TYPE), new Method(GET_PARAMETER_NAMES_METHOD_NAME, new String[0], StringArrayVariable.STRING_ARRAY_VARIABLE_TYPE), new Method(GET_PARAMETER_VALUES_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, StringArrayVariable.STRING_ARRAY_VARIABLE_TYPE), new Method(GET_URL_METHOD_NAME, new String[0], StringVariable.STRING_VARIABLE_TYPE), new Method(REMOVE_ALL_PARAMETERS_METHOD_NAME, new String[0], null), new Method(REMOVE_HEADER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, null), new Method(REMOVE_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE }, null), new Method(REMOVE_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringVariable.STRING_VARIABLE_TYPE }, null), new Method(REPLACE_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringVariable.STRING_VARIABLE_TYPE }, null), new Method(REPLACE_PARAMETER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringArrayVariable.STRING_ARRAY_VARIABLE_TYPE }, null), new Method(SET_HEADER_METHOD_NAME, new String[] { StringVariable.STRING_VARIABLE_TYPE, StringVariable.STRING_VARIABLE_TYPE }, null) }; // The actual HTTP request that we will use to perform all processing. protected HTTPRequest httpRequest; /** * Creates a new variable with no name, to be used only when creating a * variable with <CODE>Class.newInstance()</CODE>, and only when * <CODE>setName()</CODE> is called after that to set the name. * * @throws ScriptException If a problem occurs while initializing the new * variable. */ public HTTPRequestVariable() throws ScriptException { httpRequest = null; } /** * Retrieves the name of the variable type for this variable. * * @return The name of the variable type for this variable. */ @Override() public String getVariableTypeName() { return HTTP_REQUEST_VARIABLE_TYPE; } /** * Retrieves a list of all methods defined for this variable. * * @return A list of all methods defined for this variable. */ @Override() public Method[] getMethods() { return HTTP_REQUEST_VARIABLE_METHODS; } /** * Indicates whether this variable type has a method with the specified name. * * @param methodName The name of the method. * * @return <CODE>true</CODE> if this variable has a method with the specified * name, or <CODE>false</CODE> if it does not. */ @Override() public boolean hasMethod(String methodName) { for (int i=0; i < HTTP_REQUEST_VARIABLE_METHODS.length; i++) { if (HTTP_REQUEST_VARIABLE_METHODS[i].getName().equals(methodName)) { return true; } } return false; } /** * Retrieves the method number for the method that has the specified name and * argument types, or -1 if there is no such method. * * @param methodName The name of the method. * @param argumentTypes The list of argument types for the method. * * @return The method number for the method that has the specified name and * argument types. */ @Override() public int getMethodNumber(String methodName, String[] argumentTypes) { for (int i=0; i < HTTP_REQUEST_VARIABLE_METHODS.length; i++) { if (HTTP_REQUEST_VARIABLE_METHODS[i].hasSignature(methodName, argumentTypes)) { return i; } } return -1; } /** * Retrieves the return type for the method with the specified name and * argument types. * * @param methodName The name of the method. * @param argumentTypes The set of argument types for the method. * * @return The return type for the method, or <CODE>null</CODE> if there is * no such method defined. */ @Override() public String getReturnTypeForMethod(String methodName, String[] argumentTypes) { for (int i=0; i < HTTP_REQUEST_VARIABLE_METHODS.length; i++) { if (HTTP_REQUEST_VARIABLE_METHODS[i].hasSignature(methodName, argumentTypes)) { return HTTP_REQUEST_VARIABLE_METHODS[i].getReturnType(); } } return null; } /** * Executes the specified method, using the provided variables as arguments * to the method, and makes the return value available to the caller. * * @param lineNumber The line number of the script in which the method * call occurs. * @param methodNumber The method number of the method to execute. * @param arguments The set of arguments to use for the method. * * @return The value returned from the method, or <CODE>null</CODE> if it * does not return a value. * * @throws ScriptException If the specified method does not exist, or if a * problem occurs while attempting to execute it. */ @Override() public Variable executeMethod(int lineNumber, int methodNumber, Argument[] arguments) throws ScriptException { switch (methodNumber) { case ADD_PARAMETER_1_METHOD_NUMBER: StringVariable sv1 = (StringVariable) arguments[0].getArgumentValue(); StringVariable sv2 = (StringVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.addParameter(sv1.getStringValue(), sv2.getStringValue()); } return null; case ADD_PARAMETER_2_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); StringArrayVariable sav = (StringArrayVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.addParameter(sv1.getStringValue(), sav.getStringValues()); } return null; case ASSIGN_1_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); try { httpRequest = new HTTPRequest(true, new URL(sv1.getStringValue())); return new BooleanVariable(true); } catch (Exception e) { return new BooleanVariable(false); } case ASSIGN_2_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); sv2 = (StringVariable) arguments[1].getArgumentValue(); try { String method = sv1.getStringValue().toLowerCase(); if (method.equals("get")) { httpRequest = new HTTPRequest(true, new URL(sv2.getStringValue())); return new BooleanVariable(true); } else if (method.equals("post")) { httpRequest = new HTTPRequest(false, new URL(sv2.getStringValue())); return new BooleanVariable(true); } else { return new BooleanVariable(false); } } catch (Exception e) { return new BooleanVariable(false); } case CLEAR_HEADERS_METHOD_NUMBER: if (httpRequest != null) { httpRequest.clearHeaders(); } return null; case GET_HEADER_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); if (httpRequest != null) { return new StringVariable( httpRequest.getHeaderMap().get(sv1.getStringValue())); } else { return new StringVariable(); } case GET_HEADER_NAMES_METHOD_NUMBER: if (httpRequest != null) { Set<String> keySet = httpRequest.getHeaderMap().keySet(); String[] headerNames = new String[keySet.size()]; keySet.toArray(headerNames); return new StringArrayVariable(headerNames); } else { return new StringArrayVariable(); } case GET_METHOD_METHOD_NUMBER: if (httpRequest != null) { return new StringVariable(httpRequest.getRequestMethod()); } else { return new StringVariable(); } case GET_PARAMETER_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); if (httpRequest != null) { return new StringVariable( httpRequest.getParameterValue(sv1.getStringValue())); } else { return new StringVariable(); } case GET_PARAMETER_NAMES_METHOD_NUMBER: if (httpRequest != null) { return new StringArrayVariable(httpRequest.getParameterNames()); } else { return new StringArrayVariable(); } case GET_PARAMETER_VALUES_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); if (httpRequest != null) { return new StringArrayVariable( httpRequest.getParameterValues(sv1.getStringValue())); } else { return new StringArrayVariable(); } case GET_URL_METHOD_NUMBER: if (httpRequest != null) { return new StringVariable(httpRequest.getBaseURL().toExternalForm()); } else { return new StringVariable(); } case REMOVE_ALL_PARAMETERS_METHOD_NUMBER: if (httpRequest != null) { httpRequest.removeAllParameters(); } return null; case REMOVE_HEADER_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); if (httpRequest != null) { httpRequest.removeHeader(sv1.getStringValue()); } return null; case REMOVE_PARAMETER_1_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); if (httpRequest != null) { httpRequest.removeParameter(sv1.getStringValue()); } return null; case REMOVE_PARAMETER_2_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); sv2 = (StringVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.removeParameter(sv1.getStringValue(), sv2.getStringValue()); } return null; case REPLACE_PARAMETER_1_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); sv2 = (StringVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.replaceParameter(sv1.getStringValue(), sv2.getStringValue()); } return null; case REPLACE_PARAMETER_2_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); sav = (StringArrayVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.replaceParameter(sv1.getStringValue(), sav.getStringValues()); } return null; case SET_HEADER_METHOD_NUMBER: sv1 = (StringVariable) arguments[0].getArgumentValue(); sv2 = (StringVariable) arguments[1].getArgumentValue(); if (httpRequest != null) { httpRequest.setHeader(sv1.getStringValue(), sv2.getStringValue()); } return null; default: throw new ScriptException(lineNumber, "There is no method " + methodNumber + " defined for " + getArgumentType() + " variables."); } } /** * Assigns the value of the provided argument to this variable. The value of * the provided argument must be of the same type as this variable. * * @param argument The argument whose value should be assigned to this * variable. * * @throws ScriptException If a problem occurs while performing the * assignment. */ @Override() public void assign(Argument argument) throws ScriptException { if (! argument.getArgumentType().equals(HTTP_REQUEST_VARIABLE_TYPE)) { throw new ScriptException("Attempt to assign an argument of type " + argument.getArgumentType() + " to a variable of type " + HTTP_REQUEST_VARIABLE_TYPE + " rejected."); } HTTPRequestVariable hrv = (HTTPRequestVariable) argument.getArgumentValue(); httpRequest = hrv.httpRequest; } /** * Retrieves a string representation of the value of this argument. * * @return A string representation of the value of this argument. */ public String getValueAsString() { if (httpRequest == null) { return "null"; } else { return httpRequest.getRequestMethod() + ' ' + httpRequest.getBaseURL(); } } }