/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.filters;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.geotools.util.Converters;
public class BufferedRequestWrapper extends HttpServletRequestWrapper {
protected HttpServletRequest myWrappedRequest;
protected byte[] myBuffer;
protected String charset;
protected ServletInputStream myStream = null;
protected BufferedReader myReader = null;
protected Map myParameterMap;
protected Logger logger =
org.geotools.util.logging.Logging.getLogger("org.geoserver.filters");
public BufferedRequestWrapper(HttpServletRequest req, String charset, byte[] buff) {
super(req);
this.myWrappedRequest = req;
this.myBuffer = buff;
this.charset = charset;
}
public ServletInputStream getInputStream() throws IOException{
if (myStream == null) {
if (myReader == null){
myStream = new BufferedRequestStream(myBuffer);
} else {
throw new IOException("Requesting a stream after a reader is already in use!!");
}
}
return myStream;
}
public BufferedReader getReader() throws IOException{
if (myReader == null){
if (myStream == null){
myReader = new BufferedReader(new InputStreamReader(new BufferedRequestStream(
myBuffer), charset));
} else {
throw new IOException("Requesting a reader after a stream is already in use!!");
}
}
return myReader;
}
public String getParameter(String name){
parseParameters();
List allValues = (List)myParameterMap.get(name);
if (allValues != null && allValues.size() > 0){
return (String) allValues.get(0);
} else return null;
}
public Map getParameterMap(){
parseParameters();
Map toArrays = new TreeMap();
Iterator it = myParameterMap.entrySet().iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
toArrays.put(entry.getKey(),
((List)entry.getValue()).toArray(new String[0]));
}
return Collections.unmodifiableMap(toArrays);
}
public Enumeration getParameterNames(){
parseParameters();
return new IteratorAsEnumeration(myParameterMap.keySet().iterator());
}
public String[] getParameterValues(String name){
parseParameters();
List allValues = (List)myParameterMap.get(name);
if (allValues != null && allValues.size() > 0){
return (String[])allValues.toArray(new String[0]);
} else return null;
}
protected void parseParameters(){
if (myParameterMap != null) return;
String contentType = myWrappedRequest.getContentType();
if (myWrappedRequest.getMethod().equals("POST") && contentType != null
&& contentType.startsWith("application/x-www-form-urlencoded")) {
parseFormBody();
} else {
myParameterMap = new HashMap(super.getParameterMap());
for (Object key : myParameterMap.keySet()) {
Object value = myParameterMap.get(key);
if (value instanceof List) {
// ok, nothing to do
} else if (value instanceof String[]) {
myParameterMap.put(key, Arrays.asList(((String[]) value)));
} else {
myParameterMap.put(key, Converters.convert(value, List.class));
}
}
}
}
protected void parseFormBody(){
myParameterMap = new TreeMap();
// parse the body
String[] pairs;
try {
pairs = new String(myBuffer, charset).split("\\&");
} catch (UnsupportedEncodingException e) {
// should not happen
throw new RuntimeException(e);
}
for (int i = 0; i < pairs.length; i++){
parsePair(pairs[i]);
}
// we should also parse parameters that came into the request thought
if(myWrappedRequest.getQueryString() != null) {
pairs = myWrappedRequest.getQueryString().split("\\&");
for (int i = 0; i < pairs.length; i++){
parsePair(pairs[i]);
}
}
}
protected void parsePair(String pair){
int index = 0;
String[] split = pair.split("=", 2);
try{
String key = URLDecoder.decode(split[0], "UTF-8");
String value = (split.length > 1 ? URLDecoder.decode(split[1], "UTF-8") : "");
if (!myParameterMap.containsKey(key)){
myParameterMap.put(key, new ArrayList());
}
((List)myParameterMap.get(key)).add(value);
} catch (UnsupportedEncodingException e){
logger.severe("Failed to decode form values in LoggingFilter");
// we have the encoding hard-coded for now so no exceptions should be thrown...
}
}
private class IteratorAsEnumeration implements Enumeration{
Iterator it;
public IteratorAsEnumeration(Iterator it){
this.it = it;
}
public boolean hasMoreElements(){
return it.hasNext();
}
public Object nextElement(){
return it.next();
}
}
}