/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. ******************************************************************************/ /* * Copyright 2003 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ /* * Created on 01.10.2004 * * @author rschamberger * $ID$ */ package at.gv.egovernment.moa.id.util; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequestWrapper; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.URLDecoder; /** * Special ServletRequestWrapper class which provides a more precise implementation of the getParameter* * family. This implementation cares about the order of the parameters from Query String and HTTP POST * Body. Use this as Filter class for Servlets which such needs. * * @author Rudolf Schamberger * @version $Id$ */ public class InOrderServletRequestWrapper extends HttpServletRequestWrapper { /** * standard encoding used to decode the URL string. */ // public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1"; /** * Vector that stores the order of the query paramters */ private Vector queryParamOrder; /** * Hashtable that stores the content of the query paramters */ private Hashtable queryParameters; /** * Vector that stores the order of the HTTP body paramters */ private Vector bodyParamOrder; /** * Hashtable that stores the content of the HTTP body paramters */ private Hashtable bodyParameters; /** * ServletContext */ private ServletContext context; /** * Identifier used to identify query parameters */ public static final int QUERY_PARAM = 1; /** * Identifier used to identify HTTP body parameters */ public static final int BODY_PARAM = 2; /** * @see HttpServletRequestWrapper */ public InOrderServletRequestWrapper(final HttpServletRequest request, final ServletContext sContext) { super(request); this.context = sContext; } /** * parses the Query and if availlable also HTTP POST parameters * * @param req a HttpServletRequest which should be parsed */ protected final void parseParameters(final HttpServletRequest req) { queryParamOrder = new Vector(); queryParameters = new Hashtable(); bodyParamOrder = new Vector(); bodyParameters = new Hashtable(); //Insert code for Query string parsing String rawQuery = req.getQueryString(); queryParameters = tokenize(queryParameters, queryParamOrder, rawQuery, DEFAULT_CHARACTER_ENCODING, true); //analyze HTTP Post body parameters if (req.getMethod().equalsIgnoreCase("POST")) { //get body encoding String enc = req.getCharacterEncoding(); if (enc == null) enc = DEFAULT_CHARACTER_ENCODING; if (req.getContentType().equals("application/x-www-form-urlencoded")) { try { bodyParameters = parsePostData(bodyParameters, req.getContentLength(), req.getInputStream(), enc); } catch (IOException e) { context.log("could not open input stream of reqest \n" + e.toString()); } } else { //TODO add multipart code context.log( "ERROR other Content-Types than 'application/x-www-form-urlencoded' not supported!"); } }// end POST } /** * parses the HTTP POST parameters * * @param ht parameter Hashtable to put parameters in. * @param length of content * @param instream the ServletInputStream of the request * @param encoding encoding of the instream * * @return the Hashtable with the parsed data */ private Hashtable parsePostData(Hashtable ht, final int length, final ServletInputStream instream, final String encoding) { int inputLen, offset; byte[] postedBytes = null; boolean dataRemaining = true; String postedBody; StringBuffer sb = new StringBuffer(); if (length <= 0) { return null; } postedBytes = new byte[length]; try { offset = 0; while (dataRemaining) { inputLen = instream.read(postedBytes, offset, length - offset); if (inputLen <= 0) { throw new IOException("read error during reading the HTTP POST body"); } offset += inputLen; if ((length - offset) == 0) { dataRemaining = false; } } } catch (IOException e) { //System.out.println("Exception =" + e); return null; } postedBody = new String(postedBytes); Hashtable ht2 = tokenize(ht, bodyParamOrder, postedBody, encoding, false); return ht2; } /** * tokenizes parameter strings * * @param ht parameter Hashtable to put parameters in. * @param order Vector in which the order of the tokenized parameters will be stored. * @param parameterString String to tokenize. * @param encoding which will be used to decode the parameterString. * * @return the Hashtable with the parsed data */ private Hashtable tokenize(Hashtable ht, Vector order, final String parameterString, final String encoding, boolean decode) { String[] valArray = null; if (null == parameterString) return ht; StringTokenizer st = new StringTokenizer(parameterString, "&"); String key = null; String val = null; while (st.hasMoreTokens()) { String pair = (String) st.nextToken(); int pos = pair.indexOf('='); // if (pos == -1) // { // throw new IllegalArgumentException(); // } try { if (decode) { if (pos == -1) { // query is not a key=value pair, it is just a key key = URLDecoder.decode(pair, encoding); val = ""; // value is empty string } else { key = URLDecoder.decode(pair.substring(0, pos), encoding); val = URLDecoder.decode(pair.substring(pos + 1, pair.length()), encoding); } } else { if (pos == -1) { // query is not a key=value pair, it is just a key key = pair; val = ""; // value is empty string } else { key = pair.substring(0, pos); val = pair.substring(pos + 1, pair.length()); } } //Logger.debug("(" + Integer.toString(key.length()) + "=" + Integer.toString(pair.substring(0, pos).length()) + ")"+key+"|--|"+pair.substring(0, pos)); //Logger.debug("(" + Integer.toString(val.length()) + "=" + Integer.toString(pair.substring(pos + 1, pair.length()).length()) + ")"+val+"|--|"+pair.substring(pos + 1, pair.length())); } catch (Exception e) { Logger.error("Error encoding query", e); throw new IllegalArgumentException(); } if (ht.containsKey(key)) { String oldVals[] = (String[]) ht.get(key); valArray = new String[oldVals.length + 1]; for (int i = 0; i < oldVals.length; i++) { valArray[i] = oldVals[i]; } valArray[oldVals.length] = val; } else { valArray = new String[1]; valArray[0] = val; } ht.put(key, valArray); order.addElement(key); } return ht; } /** * Returns the value of a request parameter as a String, or null if the * parameter does not exist. Request parameters are extra information sent with the request. For HTTP * servlets, parameters are contained in the query string or posted form data. * *

* You should only use this method when you are sure the parameter has only one value. If the parameter * might have more than one value, use {@link #getParameterValues(String, int)}. * *

* If you use this method with a multivalued parameter, the value returned is equal to the first value in * the array returned by getParameterValues. * *

* If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then * reading the body directly via {@link #getInputStream} or {@link #getReader}can interfere with the * execution of this method. * * @param name a String containing the name of the parameter whose value is requested * * @return a String representing the single value of the parameter * * @see #getParameterValues(String, int) * */ public final String getParameter(final String name) { String val = getParameter(name, QUERY_PARAM); return (null != val) ? val : getParameter(name, BODY_PARAM); } /** * Returns the value of a request parameter as a String, or null if the * parameter does not exist. * * @param name a String containing the name of the parameter whose value is requested * @param parameterType type of parameter * @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#QUERY_PARAM * and @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#BODY_PARAM * @see #getParameterValues(String) * @return value of the (single) parameter or null if not availlable **/ public final String getParameter(final String name, final int parameterType) { Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters; String[] vals = (String[]) parameters.get(name); if (vals == null) { return null; } return vals[0]; } /** * Returns an array of String objects containing all of the values the given request * parameter has, or null if the parameter does not exist. * *

* If the parameter has a single value, the array has a length of 1. * * @param name a String containing the name of the parameter whose value is requested * @param parameterType type of parameter * @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#QUERY_PARAM * and @see at.gv.egovernment.moa.id.util.InOrderServletRequestWrapper#BODY_PARAM * @return an array of String objects containing the parameter's values or null * * @see #getParameter */ public final String getParameterValues(final String name, final int parameterType) { Hashtable parameters = (parameterType == QUERY_PARAM) ? queryParameters : bodyParameters; String[] vals = (String[]) parameters.get(name); if (vals == null) { return null; } String vallist = vals[0]; for (int i = 1; i < vals.length; i++) { vallist = vallist + "," + vals[i]; } return vallist; } /** * * Returns an Enumeration of String objects containing the names of the * parameters. If there are no parameters, the method returns an empty * Enumeration. * * @return an Enumeration of String objects, each String * containing the name of a request parameter; or an empty Enumeration if the * request has no parameters * */ public final Enumeration getParameterNames() { Vector FullParamOrder = new Vector(); for (Enumeration enu = queryParamOrder.elements(); enu.hasMoreElements();) { FullParamOrder.addElement(enu.nextElement()); } for (Enumeration enu = bodyParamOrder.elements(); enu.hasMoreElements();) { FullParamOrder.addElement(enu.nextElement()); } return FullParamOrder.elements(); } /** * * Returns an Enumeration of String objects containing the names of the * parameters contained in this request. If the request has no parameters, the method returns an empty * Enumeration. * @param parameterType type of parameter * * @return an Enumeration of String objects, each String * containing the name of a request parameter; or an empty Enumeration if the * request has no parameters * */ public final Enumeration getParameterNames(final int parameterType) { if (QUERY_PARAM == parameterType) return queryParamOrder.elements(); else return bodyParamOrder.elements(); } } //End InOrderServletRequestWrapper