* Major reshuffling of servlet/request code.
* Implement req.cookies, req.params, req.postParams and req.queryParams collections * Improve access to parameter values as array: param_array is always available even with just one value * Implement req.getHeader(name), req.getHeaders(name), req.getIntHeader(name), req.getDateHeader(name) * Implement res.setHeader(name), res.setDateHeader(name), res.addHeader(name), res.addDateHeader(name)
This commit is contained in:
parent
acb9676f0c
commit
524028da3a
5 changed files with 550 additions and 214 deletions
|
@ -82,59 +82,114 @@ public class RequestBean implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Proxy to HttpServletRequest.getHeader().
|
||||||
*
|
* @param name the header name
|
||||||
* @return ...
|
* @return the header value, or null
|
||||||
|
*/
|
||||||
|
public String getHeader(String name) {
|
||||||
|
return req.getHeader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getHeaders(), returns header values as string array.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the header values as string array
|
||||||
|
*/
|
||||||
|
public String[] getHeaders(String name) {
|
||||||
|
return req.getHeaders(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getIntHeader(), fails silently by returning -1.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the header parsed as integer or -1
|
||||||
|
*/
|
||||||
|
public int getIntHeader(String name) {
|
||||||
|
return req.getIntHeader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getDateHeader(), fails silently by returning -1.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the date in milliseconds, or -1
|
||||||
|
*/
|
||||||
|
public long getDateHeader(String name) {
|
||||||
|
return req.getDateHeader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A string representation of this request
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[Request]";
|
return "[Request]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// property related methods:
|
/**
|
||||||
|
* @return the invoked action
|
||||||
|
*/
|
||||||
public String getAction() {
|
public String getAction() {
|
||||||
return req.getAction();
|
return req.getAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return The req.data map containing request parameters, cookies and
|
||||||
*
|
* assorted HTTP headers
|
||||||
* @return ...
|
|
||||||
*/
|
*/
|
||||||
public Map getData() {
|
public Map getData() {
|
||||||
return req.getRequestData();
|
return req.getRequestData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return the req.params map containing combined query and post parameters
|
||||||
*
|
*/
|
||||||
* @return ...
|
public Map getParams() {
|
||||||
|
return req.getParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the req.queryParams map containing parameters parsed from the query string
|
||||||
|
*/
|
||||||
|
public Map getQueryParams() {
|
||||||
|
return req.getQueryParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the req.postParams map containing params parsed from post data
|
||||||
|
*/
|
||||||
|
public Map getPostParams() {
|
||||||
|
return req.getPostParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the req.cookies map containing request cookies
|
||||||
|
*/
|
||||||
|
public Map getCookies() {
|
||||||
|
return req.getCookies();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the time this request has been running, in milliseconds
|
||||||
*/
|
*/
|
||||||
public long getRuntime() {
|
public long getRuntime() {
|
||||||
return (System.currentTimeMillis() - req.getStartTime());
|
return (System.currentTimeMillis() - req.getStartTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return the password if using HTTP basic authentication
|
||||||
*
|
|
||||||
* @return ...
|
|
||||||
*/
|
*/
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return req.getPassword();
|
return req.getPassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return the request path
|
||||||
*
|
|
||||||
* @return ...
|
|
||||||
*/
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return req.getPath();
|
return req.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return the username if using HTTP basic authentication
|
||||||
*
|
|
||||||
* @return ...
|
|
||||||
*/
|
*/
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return req.getUsername();
|
return req.getUsername();
|
||||||
|
|
|
@ -18,9 +18,11 @@ package helma.framework;
|
||||||
|
|
||||||
import helma.util.Base64;
|
import helma.util.Base64;
|
||||||
import helma.util.SystemMap;
|
import helma.util.SystemMap;
|
||||||
|
import helma.util.StringUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -58,7 +60,9 @@ public class RequestTrans implements Serializable {
|
||||||
private String session;
|
private String session;
|
||||||
|
|
||||||
// the map of form and cookie data
|
// the map of form and cookie data
|
||||||
private final Map values = new SystemMap();
|
private final Map values = new DataComboMap();
|
||||||
|
|
||||||
|
private Map params, queryParams, postParams, cookies;
|
||||||
|
|
||||||
// the HTTP request method
|
// the HTTP request method
|
||||||
private String method;
|
private String method;
|
||||||
|
@ -100,6 +104,51 @@ public class RequestTrans implements Serializable {
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// do standard HTTP variables
|
||||||
|
String header = request.getHeader("Host");
|
||||||
|
if (header != null) {
|
||||||
|
values.put("http_host", header.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getHeader("Referer");
|
||||||
|
if (header != null) {
|
||||||
|
values.put("http_referer", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
|
||||||
|
if (ifModifiedSince > -1) {
|
||||||
|
setIfModifiedSince(ifModifiedSince);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
// not a date header
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getHeader("If-None-Match");
|
||||||
|
if (header != null) {
|
||||||
|
setETags(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getRemoteAddr();
|
||||||
|
if (header != null) {
|
||||||
|
values.put("http_remotehost", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getHeader("User-Agent");
|
||||||
|
if (header != null) {
|
||||||
|
values.put("http_browser", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getHeader("Accept-Language");
|
||||||
|
if (header != null) {
|
||||||
|
values.put("http_language", header);
|
||||||
|
}
|
||||||
|
|
||||||
|
header = request.getHeader("authorization");
|
||||||
|
if (header != null) {
|
||||||
|
values.put("authorization", header);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,41 +171,96 @@ public class RequestTrans implements Serializable {
|
||||||
return XMLRPC.equals(method);
|
return XMLRPC.equals(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a cookie
|
||||||
|
* @param name the cookie name
|
||||||
|
* @param cookie the cookie
|
||||||
|
*/
|
||||||
|
public void setCookie(String name, Cookie cookie) {
|
||||||
|
if (cookies == null) {
|
||||||
|
cookies = new ParameterMap();
|
||||||
|
}
|
||||||
|
cookies.put(name, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a map containing the cookies sent with this request
|
||||||
|
*/
|
||||||
|
public Map getCookies() {
|
||||||
|
if (cookies == null) {
|
||||||
|
cookies = new ParameterMap();
|
||||||
|
}
|
||||||
|
return cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the combined query and post parameters for this request
|
||||||
|
*/
|
||||||
|
public Map getParams() {
|
||||||
|
if (params == null) {
|
||||||
|
params = new ParamComboMap();
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return get the query parameters for this request
|
||||||
|
*/
|
||||||
|
public Map getQueryParams() {
|
||||||
|
if (queryParams == null) {
|
||||||
|
queryParams = new ParameterMap();
|
||||||
|
}
|
||||||
|
return queryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return get the post parameters for this request
|
||||||
|
*/
|
||||||
|
public Map getPostParams() {
|
||||||
|
if (postParams == null) {
|
||||||
|
postParams = new ParameterMap();
|
||||||
|
}
|
||||||
|
return postParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the request parameters
|
||||||
|
*/
|
||||||
|
public void setParameters(Map parameters, boolean isPost) {
|
||||||
|
if (isPost) {
|
||||||
|
postParams = new ParameterMap(parameters);
|
||||||
|
} else {
|
||||||
|
queryParams = new ParameterMap(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a post parameter to the request
|
||||||
|
* @param name the parameter name
|
||||||
|
* @param value the parameter value
|
||||||
|
*/
|
||||||
|
public void addPostParam(String name, Object value) {
|
||||||
|
if (postParams == null) {
|
||||||
|
postParams = new ParameterMap();
|
||||||
|
}
|
||||||
|
Object previous = postParams.get(name);
|
||||||
|
if (previous instanceof Object[]) {
|
||||||
|
Object[] array = (Object[]) previous;
|
||||||
|
Object[] values = new Object[array.length + 1];
|
||||||
|
System.arraycopy(array, 0, values, 0, array.length);
|
||||||
|
values[array.length] = value;
|
||||||
|
postParams.put(name, values);
|
||||||
|
} else if (previous == null) {
|
||||||
|
postParams.put(name, new Object[] {value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a parameter value in this request transmitter. This
|
* Set a parameter value in this request transmitter. This
|
||||||
* parses foo[bar][baz] as nested objects/maps.
|
* parses foo[bar][baz] as nested objects/maps.
|
||||||
*/
|
*/
|
||||||
public void set(String name, Object value) {
|
public void set(String name, Object value) {
|
||||||
int bracket = name.indexOf('[');
|
values.put(name, value);
|
||||||
Object previousValue;
|
|
||||||
if (bracket > -1 && name.endsWith("]")) {
|
|
||||||
Matcher m = paramPattern.matcher(name);
|
|
||||||
String partName = name.substring(0, bracket);
|
|
||||||
Map map = values;
|
|
||||||
while (m.find()) {
|
|
||||||
previousValue = map.get(partName);
|
|
||||||
Map partMap;
|
|
||||||
if (previousValue == null) {
|
|
||||||
partMap = new SystemMap();
|
|
||||||
map.put(partName, partMap);
|
|
||||||
} else if (previousValue instanceof Map) {
|
|
||||||
partMap = (Map) previousValue;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Conflicting HTTP Parameters for '" + name + "'");
|
|
||||||
}
|
|
||||||
partName = m.group(1);
|
|
||||||
map = partMap;
|
|
||||||
}
|
|
||||||
previousValue = map.put(partName, value);
|
|
||||||
if (previousValue != null &&
|
|
||||||
(!(previousValue instanceof Object[]) || ! partName.endsWith("_array")))
|
|
||||||
throw new RuntimeException("Conflicting HTTP Parameters for '" + name + "'");
|
|
||||||
} else {
|
|
||||||
previousValue = values.put(name, value);
|
|
||||||
if (previousValue != null &&
|
|
||||||
(!(previousValue instanceof Object[]) || !name.endsWith("_array")))
|
|
||||||
throw new RuntimeException("Conflicting HTTP Parameters for '" + name + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,6 +289,51 @@ public class RequestTrans implements Serializable {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getHeader().
|
||||||
|
* @param name the header name
|
||||||
|
* @return the header value, or null
|
||||||
|
*/
|
||||||
|
public String getHeader(String name) {
|
||||||
|
return request == null ? null : request.getHeader(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getHeaders(), returns header values as string array.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the header values as string array
|
||||||
|
*/
|
||||||
|
public String[] getHeaders(String name) {
|
||||||
|
return request == null ?
|
||||||
|
null : StringUtils.collect(request.getHeaders(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getIntHeader(), fails silently by returning -1.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the header parsed as integer or -1
|
||||||
|
*/
|
||||||
|
public int getIntHeader(String name) {
|
||||||
|
try {
|
||||||
|
return request == null ? -1 : getIntHeader(name);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletRequest.getDateHeader(), fails silently by returning -1.
|
||||||
|
* @param name the header name
|
||||||
|
* @return the date in milliseconds, or -1
|
||||||
|
*/
|
||||||
|
public long getDateHeader(String name) {
|
||||||
|
try {
|
||||||
|
return request == null ? -1 : getDateHeader(name);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Servlet response for this request.
|
* Returns the Servlet response for this request.
|
||||||
* Returns null for internal and XML-RPC requests.
|
* Returns null for internal and XML-RPC requests.
|
||||||
|
@ -425,4 +574,142 @@ public class RequestTrans implements Serializable {
|
||||||
httpPassword = null;
|
httpPassword = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ParameterMap extends SystemMap {
|
||||||
|
|
||||||
|
public ParameterMap() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParameterMap(Map map) {
|
||||||
|
super((int) (map.size() / 0.75f) + 1);
|
||||||
|
for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) {
|
||||||
|
Map.Entry e = (Map.Entry) i.next();
|
||||||
|
put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object put(Object key, Object value) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
String name = (String) key;
|
||||||
|
int bracket = name.indexOf('[');
|
||||||
|
if (bracket > -1 && name.endsWith("]")) {
|
||||||
|
Matcher matcher = paramPattern.matcher(name);
|
||||||
|
String partName = name.substring(0, bracket);
|
||||||
|
return putInternal(partName, matcher, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object previous = super.get(key);
|
||||||
|
if (previous != null && (!(previous instanceof Object[]) || !(value instanceof Object[])))
|
||||||
|
throw new RuntimeException("Conflicting HTTP Parameters for '" + key + "'");
|
||||||
|
return super.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object putInternal(String name, Matcher matcher, Object value) {
|
||||||
|
Object previous = super.get(name);
|
||||||
|
if (matcher.find()) {
|
||||||
|
ParameterMap map = null;
|
||||||
|
if (previous instanceof ParameterMap) {
|
||||||
|
map = (ParameterMap) previous;
|
||||||
|
} else if (previous == null) {
|
||||||
|
map = new ParameterMap();
|
||||||
|
super.put(name, map);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Conflicting HTTP Parameters for '" + name + "'");
|
||||||
|
}
|
||||||
|
String partName = matcher.group(1);
|
||||||
|
return map.putInternal(partName, matcher, value);
|
||||||
|
}
|
||||||
|
if (previous != null && (!(previous instanceof Object[]) || !(value instanceof Object[])))
|
||||||
|
throw new RuntimeException("Conflicting HTTP Parameters for '" + name + "'");
|
||||||
|
return super.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(Object key) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
Object value = super.get(key);
|
||||||
|
String name = (String) key;
|
||||||
|
if (name.endsWith("_array") && value == null) {
|
||||||
|
value = super.get(name.substring(0, name.length() - 6));
|
||||||
|
return value instanceof Object[] ? value : null;
|
||||||
|
} else if (name.endsWith("_cookie") && value == null) {
|
||||||
|
System.err.println(" *** *** *** " + name.substring(0, name.length() - 7));
|
||||||
|
value = super.get(name.substring(0, name.length() - 7));
|
||||||
|
return value instanceof Cookie ? value : null;
|
||||||
|
} else if (value instanceof Object[]) {
|
||||||
|
Object[] values = ((Object[]) value);
|
||||||
|
return values.length > 0 ? values[0] : null;
|
||||||
|
} else if (value instanceof Cookie) {
|
||||||
|
Cookie cookie = (Cookie) value;
|
||||||
|
return cookie.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataComboMap extends SystemMap {
|
||||||
|
|
||||||
|
public Object get(Object key) {
|
||||||
|
Object value = super.get(key);
|
||||||
|
if (value != null)
|
||||||
|
return value;
|
||||||
|
if (postParams != null && (value = postParams.get(key)) != null)
|
||||||
|
return value;
|
||||||
|
if (queryParams != null && (value = queryParams.get(key)) != null)
|
||||||
|
return value;
|
||||||
|
if (cookies != null && (value = cookies.get(key)) != null)
|
||||||
|
return value;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return get(key) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set entrySet() {
|
||||||
|
Set entries = new HashSet(super.entrySet());
|
||||||
|
if (postParams != null) entries.addAll(postParams.entrySet());
|
||||||
|
if (queryParams != null) entries.addAll(queryParams.entrySet());
|
||||||
|
if (cookies != null) entries.addAll(cookies.entrySet());
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set keySet() {
|
||||||
|
Set keys = new HashSet(super.keySet());
|
||||||
|
if (postParams != null) keys.addAll(postParams.keySet());
|
||||||
|
if (queryParams != null) keys.addAll(queryParams.keySet());
|
||||||
|
if (cookies != null) keys.addAll(cookies.keySet());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParamComboMap extends SystemMap {
|
||||||
|
public Object get(Object key) {
|
||||||
|
Object value;
|
||||||
|
if (postParams != null && (value = postParams.get(key)) != null)
|
||||||
|
return value;
|
||||||
|
if (queryParams != null && (value = queryParams.get(key)) != null)
|
||||||
|
return value;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return get(key) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set entrySet() {
|
||||||
|
Set entries = new HashSet();
|
||||||
|
if (postParams != null) entries.addAll(postParams.entrySet());
|
||||||
|
if (queryParams != null) entries.addAll(queryParams.entrySet());
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set keySet() {
|
||||||
|
Set keys = new HashSet();
|
||||||
|
if (postParams != null) keys.addAll(postParams.keySet());
|
||||||
|
if (queryParams != null) keys.addAll(queryParams.keySet());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,6 +296,43 @@ public class ResponseBean implements Serializable {
|
||||||
res.setContentType(contentType);
|
res.setContentType(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.addHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void addHeader(String name, String value) {
|
||||||
|
res.addHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.addDateHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void addDateHeader(String name, Date value) {
|
||||||
|
res.addDateHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.setHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void setHeader(String name, String value) {
|
||||||
|
res.setHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.setDateHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void setDateHeader(String name, Date value) {
|
||||||
|
res.setDateHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data map for the response
|
* Get the data map for the response
|
||||||
*
|
*
|
||||||
|
|
|
@ -484,6 +484,50 @@ public final class ResponseTrans extends Writer implements Serializable {
|
||||||
response = what;
|
response = what;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.addHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void addHeader(String name, String value) {
|
||||||
|
HttpServletResponse res = getServletResponse();
|
||||||
|
if (res != null)
|
||||||
|
res.addHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.addDateHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void addDateHeader(String name, Date value) {
|
||||||
|
HttpServletResponse res = getServletResponse();
|
||||||
|
if (res != null)
|
||||||
|
res.addDateHeader(name, value.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.setHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void setHeader(String name, String value) {
|
||||||
|
HttpServletResponse res = getServletResponse();
|
||||||
|
if (res != null)
|
||||||
|
res.setHeader(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy to HttpServletResponse.setDateHeader()
|
||||||
|
* @param name the header name
|
||||||
|
* @param value the header value
|
||||||
|
*/
|
||||||
|
public void setDateHeader(String name, Date value) {
|
||||||
|
HttpServletResponse res = getServletResponse();
|
||||||
|
if (res != null)
|
||||||
|
res.setDateHeader(name, value.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a vanilla error report. Callers should make sure the ResponeTrans is
|
* Write a vanilla error report. Callers should make sure the ResponeTrans is
|
||||||
* new or has been reset.
|
* new or has been reset.
|
||||||
|
|
|
@ -27,11 +27,8 @@ import java.util.*;
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.*;
|
import javax.servlet.http.*;
|
||||||
|
|
||||||
import org.apache.commons.fileupload.FileItem;
|
|
||||||
import org.apache.commons.fileupload.FileUploadBase;
|
|
||||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||||
import org.apache.commons.fileupload.FileUpload;
|
import org.apache.commons.fileupload.*;
|
||||||
import org.apache.commons.fileupload.ProgressListener;
|
|
||||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||||
import org.apache.commons.fileupload.servlet.ServletRequestContext;
|
import org.apache.commons.fileupload.servlet.ServletRequestContext;
|
||||||
|
|
||||||
|
@ -162,55 +159,20 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
Cookie[] reqCookies = request.getCookies();
|
Cookie[] reqCookies = request.getCookies();
|
||||||
|
|
||||||
if (reqCookies != null) {
|
if (reqCookies != null) {
|
||||||
for (int i = 0; i < reqCookies.length; i++)
|
for (int i = 0; i < reqCookies.length; i++) {
|
||||||
try {
|
try {
|
||||||
// get Cookies
|
// get Cookies
|
||||||
String nextKey = reqCookies[i].getName();
|
String key = reqCookies[i].getName();
|
||||||
String nextPart = reqCookies[i].getValue();
|
|
||||||
|
|
||||||
if (sessionCookieName.equals(nextKey)) {
|
if (sessionCookieName.equals(key)) {
|
||||||
reqtrans.setSession(nextPart);
|
reqtrans.setSession(reqCookies[i].getValue());
|
||||||
} else {
|
} else {
|
||||||
reqtrans.set(nextKey, nextPart);
|
reqtrans.setCookie(key, reqCookies[i]);
|
||||||
}
|
}
|
||||||
} catch (Exception badCookie) {
|
} catch (Exception badCookie) {
|
||||||
// ignore
|
log("Error setting cookie", badCookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// do standard HTTP variables
|
|
||||||
String host = request.getHeader("Host");
|
|
||||||
|
|
||||||
if (host != null) {
|
|
||||||
host = host.toLowerCase();
|
|
||||||
reqtrans.set("http_host", host);
|
|
||||||
}
|
|
||||||
|
|
||||||
String referer = request.getHeader("Referer");
|
|
||||||
|
|
||||||
if (referer != null) {
|
|
||||||
reqtrans.set("http_referer", referer);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
|
|
||||||
|
|
||||||
if (ifModifiedSince > -1) {
|
|
||||||
reqtrans.setIfModifiedSince(ifModifiedSince);
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
String ifNoneMatch = request.getHeader("If-None-Match");
|
|
||||||
|
|
||||||
if (ifNoneMatch != null) {
|
|
||||||
reqtrans.setETags(ifNoneMatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
String remotehost = request.getRemoteAddr();
|
|
||||||
|
|
||||||
if (remotehost != null) {
|
|
||||||
reqtrans.set("http_remotehost", remotehost);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the cookie domain to use for this response, if any.
|
// get the cookie domain to use for this response, if any.
|
||||||
|
@ -222,11 +184,11 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
// check for x-forwarded-for header, fix for bug 443
|
// check for x-forwarded-for header, fix for bug 443
|
||||||
String proxiedHost = request.getHeader("x-forwarded-host");
|
String proxiedHost = request.getHeader("x-forwarded-host");
|
||||||
if (proxiedHost != null) {
|
if (proxiedHost != null) {
|
||||||
if (proxiedHost.toLowerCase().indexOf(cookieDomain) == -1) {
|
if (proxiedHost.toLowerCase().indexOf(resCookieDomain) == -1) {
|
||||||
resCookieDomain = null;
|
resCookieDomain = null;
|
||||||
}
|
}
|
||||||
} else if ((host != null) &&
|
} else if ((host != null) &&
|
||||||
host.toLowerCase().indexOf(cookieDomain) == -1) {
|
host.toLowerCase().indexOf(resCookieDomain) == -1) {
|
||||||
resCookieDomain = null;
|
resCookieDomain = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,93 +196,23 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
// check if session cookie is present and valid, creating it if not.
|
// check if session cookie is present and valid, creating it if not.
|
||||||
checkSessionCookie(request, response, reqtrans, resCookieDomain);
|
checkSessionCookie(request, response, reqtrans, resCookieDomain);
|
||||||
|
|
||||||
String browser = request.getHeader("User-Agent");
|
|
||||||
|
|
||||||
if (browser != null) {
|
|
||||||
reqtrans.set("http_browser", browser);
|
|
||||||
}
|
|
||||||
|
|
||||||
String language = request.getHeader("Accept-Language");
|
|
||||||
|
|
||||||
if (language != null) {
|
|
||||||
reqtrans.set("http_language", language);
|
|
||||||
}
|
|
||||||
|
|
||||||
String authorization = request.getHeader("authorization");
|
|
||||||
|
|
||||||
if (authorization != null) {
|
|
||||||
reqtrans.set("authorization", authorization);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read and set http parameters
|
// read and set http parameters
|
||||||
Map parameters = parseParameters(request, encoding);
|
parseParameters(request, reqtrans, encoding);
|
||||||
|
|
||||||
if (parameters != null) {
|
|
||||||
for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
|
|
||||||
Map.Entry entry = (Map.Entry) i.next();
|
|
||||||
String key = (String) entry.getKey();
|
|
||||||
String[] values = (String[]) entry.getValue();
|
|
||||||
|
|
||||||
if ((values != null) && (values.length > 0)) {
|
|
||||||
// set to single string value
|
|
||||||
reqtrans.set(key, values[0]);
|
|
||||||
|
|
||||||
if (values.length > 1) {
|
|
||||||
// set string array
|
|
||||||
reqtrans.set(key + "_array", values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// read file uploads
|
||||||
List uploads = null;
|
List uploads = null;
|
||||||
ServletRequestContext reqcx = new ServletRequestContext(request);
|
ServletRequestContext reqcx = new ServletRequestContext(request);
|
||||||
|
|
||||||
if (ServletFileUpload.isMultipartContent(reqcx)) {
|
if (ServletFileUpload.isMultipartContent(reqcx)) {
|
||||||
// get session for upload progress monitoring
|
// get session for upload progress monitoring
|
||||||
final UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans);
|
UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans);
|
||||||
try {
|
try {
|
||||||
// handle file upload
|
uploads = parseUploads(reqcx, reqtrans, uploadStatus, encoding);
|
||||||
DiskFileItemFactory factory = new DiskFileItemFactory();
|
|
||||||
FileUpload upload = new FileUpload(factory);
|
|
||||||
// use upload limit for individual file size, but also set a limit on overall size
|
|
||||||
upload.setFileSizeMax(uploadLimit * 1024);
|
|
||||||
upload.setSizeMax(totalUploadLimit * 1024);
|
|
||||||
|
|
||||||
// register upload tracker with user's session
|
|
||||||
if (uploadStatus != null) {
|
|
||||||
upload.setProgressListener(new ProgressListener() {
|
|
||||||
public void update(long bytesRead, long contentLength, int itemsRead) {
|
|
||||||
uploadStatus.update(bytesRead, contentLength, itemsRead);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
uploads = upload.parseRequest(reqcx);
|
|
||||||
Iterator it = uploads.iterator();
|
|
||||||
|
|
||||||
while (it.hasNext()) {
|
|
||||||
FileItem item = (FileItem) it.next();
|
|
||||||
String name = item.getFieldName();
|
|
||||||
Object value;
|
|
||||||
// check if this is an ordinary HTML form element or a file upload
|
|
||||||
if (item.isFormField()) {
|
|
||||||
value = item.getString(encoding);
|
|
||||||
} else {
|
|
||||||
value = new MimePart(item);
|
|
||||||
}
|
|
||||||
// if multiple values exist for this name, append to _array
|
|
||||||
if (reqtrans.get(name) != null) {
|
|
||||||
appendFormValue(reqtrans, name, value);
|
|
||||||
} else {
|
|
||||||
reqtrans.set(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception upx) {
|
} catch (Exception upx) {
|
||||||
log("Error in file upload", upx);
|
log("Error in file upload", upx);
|
||||||
String message;
|
String message;
|
||||||
if (upx instanceof FileUploadBase.SizeLimitExceededException) {
|
boolean tooLarge = (upx instanceof FileUploadBase.SizeLimitExceededException);
|
||||||
|
if (tooLarge) {
|
||||||
message = "File upload size exceeds limit of " + uploadLimit + " kB";
|
message = "File upload size exceeds limit of " + uploadLimit + " kB";
|
||||||
} else {
|
} else {
|
||||||
message = upx.getMessage();
|
message = upx.getMessage();
|
||||||
|
@ -334,13 +226,11 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
|
|
||||||
if (uploadSoftfail || uploadStatus != null) {
|
if (uploadSoftfail || uploadStatus != null) {
|
||||||
reqtrans.set("helma_upload_error", message);
|
reqtrans.set("helma_upload_error", message);
|
||||||
} else if (upx instanceof FileUploadBase.SizeLimitExceededException) {
|
|
||||||
sendError(response, HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE,
|
|
||||||
"Error in file upload: " + message);
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
int errorCode = tooLarge ?
|
||||||
"Error in file upload: " + message);
|
HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE:
|
||||||
|
HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||||
|
sendError(response, errorCode, "Error in file upload: " + message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,13 +302,15 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
} else {
|
} else {
|
||||||
if (!hopres.isCacheable() || !caching) {
|
if (!hopres.isCacheable() || !caching) {
|
||||||
// Disable caching of response.
|
// Disable caching of response.
|
||||||
// for HTTP 1.0
|
if (isOneDotOne(req.getProtocol())) {
|
||||||
res.setDateHeader("Expires", System.currentTimeMillis() - 10000);
|
|
||||||
res.setHeader("Pragma", "no-cache");
|
|
||||||
|
|
||||||
// for HTTP 1.1
|
// for HTTP 1.1
|
||||||
res.setHeader("Cache-Control",
|
res.setHeader("Cache-Control",
|
||||||
"no-cache, no-store, must-revalidate, max-age=0");
|
"no-cache, no-store, must-revalidate, max-age=0");
|
||||||
|
} else {
|
||||||
|
// for HTTP 1.0
|
||||||
|
res.setDateHeader("Expires", System.currentTimeMillis() - 10000);
|
||||||
|
res.setHeader("Pragma", "no-cache");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hopres.getRealm() != null) {
|
if (hopres.getRealm() != null) {
|
||||||
|
@ -609,30 +501,6 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to build the form value array when a multipart (file upload) form has
|
|
||||||
* multiple values for one form element name.
|
|
||||||
*
|
|
||||||
* @param reqtrans
|
|
||||||
* @param name
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
private void appendFormValue(RequestTrans reqtrans, String name, Object value) {
|
|
||||||
String arrayName = name + "_array";
|
|
||||||
try {
|
|
||||||
Object[] values = (Object[]) reqtrans.get(arrayName);
|
|
||||||
if (values == null) {
|
|
||||||
reqtrans.set(arrayName, new Object[] {reqtrans.get(name), value});
|
|
||||||
} else {
|
|
||||||
Object[] newValues = new Object[values.length + 1];
|
|
||||||
System.arraycopy(values, 0, newValues, 0, values.length);
|
|
||||||
newValues[values.length] = value;
|
|
||||||
reqtrans.set(arrayName, newValues);
|
|
||||||
}
|
|
||||||
} catch (ClassCastException x) {
|
|
||||||
// name_array is defined as something else in the form - don't overwrite it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the session cookie is set and valid for this request.
|
* Check if the session cookie is set and valid for this request.
|
||||||
|
@ -726,7 +594,46 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
map.put(name, newValues);
|
map.put(name, newValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map parseParameters(HttpServletRequest request, String encoding)
|
protected List parseUploads(ServletRequestContext reqcx, RequestTrans reqtrans,
|
||||||
|
final UploadStatus uploadStatus, String encoding)
|
||||||
|
throws FileUploadException, UnsupportedEncodingException {
|
||||||
|
// handle file upload
|
||||||
|
DiskFileItemFactory factory = new DiskFileItemFactory();
|
||||||
|
FileUpload upload = new FileUpload(factory);
|
||||||
|
// use upload limit for individual file size, but also set a limit on overall size
|
||||||
|
upload.setFileSizeMax(uploadLimit * 1024);
|
||||||
|
upload.setSizeMax(totalUploadLimit * 1024);
|
||||||
|
|
||||||
|
// register upload tracker with user's session
|
||||||
|
if (uploadStatus != null) {
|
||||||
|
upload.setProgressListener(new ProgressListener() {
|
||||||
|
public void update(long bytesRead, long contentLength, int itemsRead) {
|
||||||
|
uploadStatus.update(bytesRead, contentLength, itemsRead);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
List uploads = upload.parseRequest(reqcx);
|
||||||
|
Iterator it = uploads.iterator();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
FileItem item = (FileItem) it.next();
|
||||||
|
String name = item.getFieldName();
|
||||||
|
Object value;
|
||||||
|
// check if this is an ordinary HTML form element or a file upload
|
||||||
|
if (item.isFormField()) {
|
||||||
|
value = item.getString(encoding);
|
||||||
|
} else {
|
||||||
|
value = new MimePart(item);
|
||||||
|
}
|
||||||
|
// if multiple values exist for this name, append to _array
|
||||||
|
reqtrans.addPostParam(name, value);
|
||||||
|
}
|
||||||
|
return uploads;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void parseParameters(HttpServletRequest request, RequestTrans reqtrans,
|
||||||
|
String encoding)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// check if there are any parameters before we get started
|
// check if there are any parameters before we get started
|
||||||
String queryString = request.getQueryString();
|
String queryString = request.getQueryString();
|
||||||
|
@ -736,7 +643,7 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
&& contentType.toLowerCase().startsWith("application/x-www-form-urlencoded");
|
&& contentType.toLowerCase().startsWith("application/x-www-form-urlencoded");
|
||||||
|
|
||||||
if (queryString == null && !isFormPost) {
|
if (queryString == null && !isFormPost) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap parameters = new HashMap();
|
HashMap parameters = new HashMap();
|
||||||
|
@ -744,6 +651,10 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
// Parse any query string parameters from the request
|
// Parse any query string parameters from the request
|
||||||
if (queryString != null) {
|
if (queryString != null) {
|
||||||
parseParameters(parameters, queryString.getBytes(), encoding, false);
|
parseParameters(parameters, queryString.getBytes(), encoding, false);
|
||||||
|
if (!parameters.isEmpty()) {
|
||||||
|
reqtrans.setParameters(parameters, false);
|
||||||
|
parameters.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse any posted parameters in the input stream
|
// Parse any posted parameters in the input stream
|
||||||
|
@ -765,9 +676,11 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
|
|
||||||
// is.close();
|
// is.close();
|
||||||
parseParameters(parameters, buf, encoding, true);
|
parseParameters(parameters, buf, encoding, true);
|
||||||
|
if (!parameters.isEmpty()) {
|
||||||
|
reqtrans.setParameters(parameters, true);
|
||||||
|
parameters.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue