* 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 { | |||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * Proxy to HttpServletRequest.getHeader(). | ||||
|      * @param name the header name | ||||
|      * @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() { | ||||
|         return "[Request]"; | ||||
|     } | ||||
| 
 | ||||
|     // property related methods: | ||||
|     /** | ||||
|      * @return the invoked action | ||||
|      */ | ||||
|     public String getAction() { | ||||
|         return req.getAction(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * @return The req.data map containing request parameters, cookies and | ||||
|      * assorted HTTP headers | ||||
|      */ | ||||
|     public Map getData() { | ||||
|         return req.getRequestData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * @return the req.params map containing combined query and post parameters | ||||
|      */ | ||||
|     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() { | ||||
|         return (System.currentTimeMillis() - req.getStartTime()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * @return the password if using HTTP basic authentication | ||||
|      */ | ||||
|     public String getPassword() { | ||||
|         return req.getPassword(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * @return the request path | ||||
|      */ | ||||
|     public String getPath() { | ||||
|         return req.getPath(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * | ||||
|      * @return ... | ||||
|      * @return the username if using HTTP basic authentication | ||||
|      */ | ||||
|     public String getUsername() { | ||||
|         return req.getUsername(); | ||||
|  |  | |||
|  | @ -18,9 +18,11 @@ package helma.framework; | |||
| 
 | ||||
| import helma.util.Base64; | ||||
| import helma.util.SystemMap; | ||||
| import helma.util.StringUtils; | ||||
| 
 | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.servlet.http.Cookie; | ||||
| import java.io.*; | ||||
| import java.util.*; | ||||
| import java.util.regex.Pattern; | ||||
|  | @ -58,7 +60,9 @@ public class RequestTrans implements Serializable { | |||
|     private String session; | ||||
| 
 | ||||
|     // 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 | ||||
|     private String method; | ||||
|  | @ -100,6 +104,51 @@ public class RequestTrans implements Serializable { | |||
|         this.response = response; | ||||
|         this.path = path; | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      * parses foo[bar][baz] as nested objects/maps. | ||||
|      */ | ||||
|     public void set(String name, Object value) { | ||||
|         int bracket = name.indexOf('['); | ||||
|         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 + "'"); | ||||
|         } | ||||
|         values.put(name, value); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -185,6 +289,51 @@ public class RequestTrans implements Serializable { | |||
|         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 null for internal and XML-RPC requests. | ||||
|  | @ -425,4 +574,142 @@ public class RequestTrans implements Serializable { | |||
|             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); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      * | ||||
|  |  | |||
|  | @ -484,6 +484,50 @@ public final class ResponseTrans extends Writer implements Serializable { | |||
|         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 | ||||
|      * new or has been reset. | ||||
|  |  | |||
|  | @ -27,11 +27,8 @@ import java.util.*; | |||
| import javax.servlet.*; | ||||
| 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.FileUpload; | ||||
| import org.apache.commons.fileupload.ProgressListener; | ||||
| import org.apache.commons.fileupload.*; | ||||
| import org.apache.commons.fileupload.servlet.ServletFileUpload; | ||||
| import org.apache.commons.fileupload.servlet.ServletRequestContext; | ||||
| 
 | ||||
|  | @ -162,55 +159,20 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|             Cookie[] reqCookies = request.getCookies(); | ||||
| 
 | ||||
|             if (reqCookies != null) { | ||||
|                 for (int i = 0; i < reqCookies.length; i++) | ||||
|                 for (int i = 0; i < reqCookies.length; i++) { | ||||
|                     try { | ||||
|                         // get Cookies | ||||
|                         String nextKey = reqCookies[i].getName(); | ||||
|                         String nextPart = reqCookies[i].getValue(); | ||||
|                         String key = reqCookies[i].getName(); | ||||
| 
 | ||||
|                         if (sessionCookieName.equals(nextKey)) { | ||||
|                             reqtrans.setSession(nextPart); | ||||
|                         if (sessionCookieName.equals(key)) { | ||||
|                             reqtrans.setSession(reqCookies[i].getValue()); | ||||
|                         } else { | ||||
|                             reqtrans.set(nextKey, nextPart); | ||||
|                             reqtrans.setCookie(key, reqCookies[i]); | ||||
|                         }                | ||||
|                     } 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. | ||||
|  | @ -222,11 +184,11 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|                 // check for x-forwarded-for header, fix for bug 443 | ||||
|                 String proxiedHost = request.getHeader("x-forwarded-host"); | ||||
|                 if (proxiedHost != null) { | ||||
|                     if (proxiedHost.toLowerCase().indexOf(cookieDomain) == -1) { | ||||
|                     if (proxiedHost.toLowerCase().indexOf(resCookieDomain) == -1) { | ||||
|                         resCookieDomain = null; | ||||
|                     } | ||||
|                 } else if ((host != null) && | ||||
|                         host.toLowerCase().indexOf(cookieDomain) == -1) { | ||||
|                         host.toLowerCase().indexOf(resCookieDomain) == -1) { | ||||
|                     resCookieDomain = null; | ||||
|                 } | ||||
|             } | ||||
|  | @ -234,93 +196,23 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|             // check if session cookie is present and valid, creating it if not. | ||||
|             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 | ||||
|             Map parameters = parseParameters(request, 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); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             parseParameters(request, reqtrans, encoding); | ||||
| 
 | ||||
|             // read file uploads | ||||
|             List uploads = null; | ||||
|             ServletRequestContext reqcx = new ServletRequestContext(request); | ||||
| 
 | ||||
|             if (ServletFileUpload.isMultipartContent(reqcx)) { | ||||
|                 // get session for upload progress monitoring | ||||
|                 final UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans); | ||||
|                 UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans); | ||||
|                 try { | ||||
|                     // 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); | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
| 
 | ||||
|                     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); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     uploads = parseUploads(reqcx, reqtrans, uploadStatus, encoding); | ||||
|                 } catch (Exception upx) { | ||||
|                     log("Error in file upload", upx); | ||||
|                     String message; | ||||
|                     if (upx instanceof FileUploadBase.SizeLimitExceededException) { | ||||
|                     boolean tooLarge = (upx instanceof FileUploadBase.SizeLimitExceededException); | ||||
|                     if (tooLarge) { | ||||
|                         message = "File upload size exceeds limit of " + uploadLimit + " kB"; | ||||
|                     } else { | ||||
|                         message = upx.getMessage(); | ||||
|  | @ -334,13 +226,11 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
| 
 | ||||
|                     if (uploadSoftfail || uploadStatus != null) { | ||||
|                         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 { | ||||
|                         sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, | ||||
|                                 "Error in file upload: " + message); | ||||
|                         int errorCode = tooLarge ? | ||||
|                                 HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE: | ||||
|                                 HttpServletResponse.SC_INTERNAL_SERVER_ERROR; | ||||
|                         sendError(response, errorCode, "Error in file upload: " + message); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -412,13 +302,15 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|         } else { | ||||
|             if (!hopres.isCacheable() || !caching) { | ||||
|                 // Disable caching of response. | ||||
|                 // for HTTP 1.0 | ||||
|                 res.setDateHeader("Expires", System.currentTimeMillis() - 10000); | ||||
|                 res.setHeader("Pragma", "no-cache"); | ||||
| 
 | ||||
|                 // for HTTP 1.1 | ||||
|                 res.setHeader("Cache-Control", | ||||
|                               "no-cache, no-store, must-revalidate, max-age=0"); | ||||
|                 if (isOneDotOne(req.getProtocol())) { | ||||
|                     // for HTTP 1.1 | ||||
|                     res.setHeader("Cache-Control", | ||||
|                                   "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) { | ||||
|  | @ -609,30 +501,6 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|         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. | ||||
|  | @ -726,7 +594,46 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|         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 { | ||||
|         // check if there are any parameters before we get started | ||||
|         String queryString = request.getQueryString(); | ||||
|  | @ -736,7 +643,7 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|                 && contentType.toLowerCase().startsWith("application/x-www-form-urlencoded"); | ||||
| 
 | ||||
|         if (queryString == null && !isFormPost) { | ||||
|             return null; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         HashMap parameters = new HashMap(); | ||||
|  | @ -744,6 +651,10 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
|         // Parse any query string parameters from the request | ||||
|         if (queryString != null) { | ||||
|             parseParameters(parameters, queryString.getBytes(), encoding, false); | ||||
|             if (!parameters.isEmpty()) { | ||||
|                 reqtrans.setParameters(parameters, false); | ||||
|                 parameters.clear(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Parse any posted parameters in the input stream | ||||
|  | @ -765,9 +676,11 @@ public abstract class AbstractServletClient extends HttpServlet { | |||
| 
 | ||||
|             // is.close(); | ||||
|             parseParameters(parameters, buf, encoding, true); | ||||
|             if (!parameters.isEmpty()) { | ||||
|                 reqtrans.setParameters(parameters, true); | ||||
|                 parameters.clear(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return parameters; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue