Author: remy.maucherat(a)jboss.com
Date: 2009-04-20 11:51:08 -0400 (Mon, 20 Apr 2009)
New Revision: 1020
Modified:
trunk/ROADMAP.txt
trunk/java/org/apache/catalina/Wrapper.java
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java
trunk/java/org/apache/catalina/core/StandardWrapper.java
trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
trunk/java/org/apache/catalina/core/StandardWrapperValve.java
trunk/java/org/apache/catalina/deploy/FilterDef.java
trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java
trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
Log:
- Add the new features to roadmap (ordering and many new annotations: ouch ...).
- Fix return types.
- Fix some issues with fileupload: getName renaming due to conflict with Part.getName :(
Modified: trunk/ROADMAP.txt
===================================================================
--- trunk/ROADMAP.txt 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/ROADMAP.txt 2009-04-20 15:51:08 UTC (rev 1020)
@@ -2,10 +2,11 @@
Main development:
- Update digester XML parsing rules for web.xml updates
-- web.xml fragments scanning (merge with Catalina .tld scanning)
+- web.xml fragments scanning and merging rules
+- web.xml fragments ordering
- Resources overlay
- Session tracking configuration
-- Multipart support (and remove fileupload)
+- Access control annotations
- JSP 2.2 changes
- EL 1.1 changes
- Setup standalone TCK environment for testing compliance with the new features
Modified: trunk/java/org/apache/catalina/Wrapper.java
===================================================================
--- trunk/java/org/apache/catalina/Wrapper.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/Wrapper.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -23,6 +23,7 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.UnavailableException;
+import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.util.InstanceSupport;
@@ -153,8 +154,20 @@
*/
public void setLoadOnStartup(int value);
+
+ /**
+ * Multipart configuration for this Servlet.
+ */
+ public MultipartConfig getMultipartConfig();
+
/**
+ * Set the multipart configuration for this Servlet.
+ */
+ public void setMultipartConfig(MultipartConfig multipartConfig);
+
+
+ /**
* Return the run-as identity for this servlet.
*/
public String getRunAs();
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-04-20 09:49:53 UTC (rev
1019)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-04-20 15:51:08 UTC (rev
1020)
@@ -58,7 +58,6 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
@@ -77,6 +76,7 @@
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletResponse;
+import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -2660,8 +2660,13 @@
} else {
contentType = contentType.trim();
}
- if (!("application/x-www-form-urlencoded".equals(contentType)))
+ if (!("application/x-www-form-urlencoded".equals(contentType))) {
+ // Check for multipart as an alternate way to send parameters
+ if (parts == null) {
+ parseMultipart();
+ }
return;
+ }
int len = getContentLength();
@@ -2704,21 +2709,49 @@
*/
protected void parseMultipart() {
- // FIXME: Stub configuration from the example
+ MultipartConfig config = wrapper.getMultipartConfig();
+ if (config == null) {
+ return;
+ }
+
+ if (usingInputStream || usingReader)
+ return;
+
+ if (!getMethod().equalsIgnoreCase("POST"))
+ return;
+
+ String contentType = getContentType();
+ if (contentType == null)
+ contentType = "";
+ int semicolon = contentType.indexOf(';');
+ if (semicolon >= 0) {
+ contentType = contentType.substring(0, semicolon).trim();
+ } else {
+ contentType = contentType.trim();
+ }
+ if (!("multipart/form-data".equals(contentType)))
+ return;
+
DiskFileUpload fu = new DiskFileUpload();
- // maximum size before a FileUploadException will be thrown
- fu.setSizeMax(1000000);
- // maximum size that will be stored in memory
- fu.setSizeThreshold(4096);
- // the location for saving data that is larger than getSizeThreshold()
- fu.setRepositoryPath("/tmp");
+ // FIXME: set default values
+ fu.setRepositoryPath(config.location());
+ if (config.fileSizeThreshold() > 0) {
+ fu.setSizeThreshold(config.fileSizeThreshold());
+ }
+ if (config.maxRequestSize() > 0) {
+ fu.setSizeMax(config.maxRequestSize());
+ }
+ // FIXME: Unimplemented per file max size:
fu.setSizeFileMax(config.maxFileSize());
parts = new HashMap<String, Part>();
try {
Iterator<FileItem> items = fu.parseRequest(getRequest()).iterator();
while (items.hasNext()) {
FileItem fileItem = items.next();
- parts.put(fileItem.getName(), fileItem);
+ if (fileItem.getFileName() == null) {
+ coyoteRequest.getParameters().addParameterValues(fileItem.getName(),
new String[] {fileItem.getString()});
+ }
+ parts.put(fileItem.getFieldName(), fileItem);
}
} catch (IOException e) {
// Client disconnect
@@ -2953,19 +2986,12 @@
}
setTimeout(timeout);
if (asyncContext == null) {
- asyncContext = new AsyncContextImpl
- ((servletRequest == null) ? getRequest() : servletRequest,
- (servletResponse == null) ? response.getResponse() : servletResponse);
+ asyncContext = new AsyncContextImpl();
eventMode = true;
} else {
- if (servletRequest != null) {
- asyncContext.setRequest(servletRequest);
- }
- if (servletResponse != null) {
- asyncContext.setResponse(servletResponse);
- }
asyncContext.reset();
}
+ asyncContext.setRequestAndResponse(servletRequest, servletResponse);
return asyncContext;
}
@@ -3090,13 +3116,9 @@
protected String path = null;
protected Runnable runnable = null;
protected boolean useAttributes = false;
+ protected boolean original = true;
protected boolean ready = true;
- public AsyncContextImpl(ServletRequest request, ServletResponse response) {
- this.request = request;
- this.response = response;
- }
-
public void complete() {
setEventMode(false);
resume();
@@ -3131,11 +3153,19 @@
}
public ServletRequest getRequest() {
- return request;
+ if (request != null) {
+ return request;
+ } else {
+ return getRequestFacade();
+ }
}
public ServletResponse getResponse() {
- return response;
+ if (response != null) {
+ return response;
+ } else {
+ return getResponseFacade();
+ }
}
public boolean hasOriginalRequestAndResponse() {
@@ -3151,11 +3181,15 @@
return ready;
}
- public void setRequest(ServletRequest request) {
- this.request = request;
+ public void done() {
+ ready = false;
}
- public void setResponse(ServletResponse response) {
+ public void setRequestAndResponse(ServletRequest request, ServletResponse
response) {
+ if (request == null && response == null) {
+
+ }
+ this.request = request;
this.response = response;
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-04-20 09:49:53
UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-04-20 15:51:08
UTC (rev 1020)
@@ -53,8 +53,10 @@
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.naming.NamingException;
import javax.servlet.DispatcherType;
@@ -304,19 +306,28 @@
public boolean setInitParameter(String name, String value) {
+ if (filterDef.getInitParameter(name) != null) {
+ return false;
+ }
filterDef.addInitParameter(name, value);
context.addFilterDef(filterDef);
return true;
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters)
{
+ Set<String> conflicts = new HashSet<String>();
Iterator<String> parameterNames = initParameters.keySet().iterator();
while (parameterNames.hasNext()) {
String parameterName = parameterNames.next();
- filterDef.addInitParameter(parameterName,
initParameters.get(parameterName));
+ if (filterDef.getInitParameter(parameterName) != null) {
+ conflicts.add(parameterName);
+ } else {
+ filterDef.addInitParameter(parameterName,
initParameters.get(parameterName));
+ }
}
- return true;
+ context.addFilterDef(filterDef);
+ return conflicts;
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java 2009-04-20
09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java 2009-04-20
15:51:08 UTC (rev 1020)
@@ -53,6 +53,7 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.naming.NamingException;
import javax.servlet.DispatcherType;
@@ -160,17 +161,17 @@
}
- public boolean addMappingForServletNames(
+ public void addMappingForServletNames(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... servletNames) {
- return config.addMappingForServletNames(dispatcherTypes, isMatchAfter,
servletNames);
+ config.addMappingForServletNames(dispatcherTypes, isMatchAfter, servletNames);
}
- public boolean addMappingForUrlPatterns(
+ public void addMappingForUrlPatterns(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... urlPatterns) {
- return config.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter,
urlPatterns);
+ config.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns);
}
@@ -179,7 +180,7 @@
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters)
{
return config.setInitParameters(initParameters);
}
Modified: trunk/java/org/apache/catalina/core/StandardWrapper.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapper.java 2009-04-20 09:49:53 UTC (rev
1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapper.java 2009-04-20 15:51:08 UTC (rev
1020)
@@ -43,6 +43,7 @@
import javax.servlet.ServletResponse;
import javax.servlet.SingleThreadModel;
import javax.servlet.UnavailableException;
+import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.Container;
import org.apache.catalina.ContainerServlet;
@@ -181,6 +182,12 @@
/**
+ * The multipart config annotation configured on this servlet.
+ */
+ protected MultipartConfig multipartConfig = null;
+
+
+ /**
* Mappings associated with the wrapper.
*/
protected ArrayList mappings = new ArrayList();
@@ -509,6 +516,22 @@
/**
+ * Multipart configuration for this Servlet.
+ */
+ public MultipartConfig getMultipartConfig() {
+ return multipartConfig;
+ }
+
+
+ /**
+ * Set the multipart configuration for this Servlet.
+ */
+ public void setMultipartConfig(MultipartConfig multipartConfig) {
+ this.multipartConfig = multipartConfig;
+ }
+
+
+ /**
* Return maximum number of instances that will be allocated when a single
* thread model servlet is used.
*/
Modified: trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-04-20 09:49:53 UTC
(rev 1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-04-20 15:51:08 UTC
(rev 1020)
@@ -48,8 +48,10 @@
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -144,17 +146,22 @@
}
- public boolean addMapping(String... urlPatterns) {
+ public Set<String> addMapping(String... urlPatterns) {
+ Set<String> conflicts = new HashSet<String>();
if (((Context) wrapper.getParent()).isInitialized()) {
throw new IllegalStateException(sm.getString
("servletRegistration.addServletMapping.ise", ((Context)
wrapper.getParent()).getPath()));
}
if (urlPatterns != null) {
for (int i = 0; i < urlPatterns.length; i++) {
- ((Context) wrapper.getParent()).addServletMapping(urlPatterns[i],
wrapper.getName());
+ if (((Context) wrapper.getParent()).findServletMapping(urlPatterns[i]) !=
null) {
+ conflicts.add(urlPatterns[i]);
+ } else {
+ ((Context) wrapper.getParent()).addServletMapping(urlPatterns[i],
wrapper.getName());
+ }
}
}
- return true;
+ return conflicts;
}
@@ -174,13 +181,18 @@
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters)
{
+ Set<String> conflicts = new HashSet<String>();
Iterator<String> parameterNames = initParameters.keySet().iterator();
while (parameterNames.hasNext()) {
String parameterName = parameterNames.next();
- wrapper.addInitParameter(parameterName, initParameters.get(parameterName));
+ if (wrapper.findInitParameter(parameterName) != null) {
+ conflicts.add(parameterName);
+ } else {
+ wrapper.addInitParameter(parameterName,
initParameters.get(parameterName));
+ }
}
- return true;
+ return conflicts;
}
Modified: trunk/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-04-20 09:49:53 UTC
(rev 1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-04-20 15:51:08 UTC
(rev 1020)
@@ -407,6 +407,9 @@
// Invoke the listeners with onComplete or onTimeout
boolean timeout = (event.getType() == EventType.TIMEOUT) ? true : false;
Iterator<AsyncEvent> asyncEvents =
asyncContext.getAsyncListeners().keySet().iterator();
+ if (timeout && !asyncEvents.hasNext()) {
+ // FIXME: MUST do an ERROR dispatch to the original URI and MUST set
the response code to 500
+ }
while (asyncEvents.hasNext()) {
AsyncEvent asyncEvent = asyncEvents.next();
AsyncListener asyncListener =
asyncContext.getAsyncListeners().get(asyncEvent);
@@ -432,6 +435,8 @@
exception(request, response, e);
}
} else if (asyncContext.getPath() != null) {
+ // We executed the dispatch
+ asyncContext.done();
// Remap the request, set the dispatch attributes, create the filter
chain
// and invoke the Servlet
Context context = (Context) getContainer().getParent();
@@ -453,6 +458,9 @@
}
// If there is no new startAsync, then close the response
if (!asyncContext.isReady()) {
+ // FIXME: see which one is the right one to close the response
+ asyncContext.complete();
+ /*
if (asyncContext.getResponse() instanceof ResponseFacade) {
response.setSuspended(true);
} else {
@@ -474,6 +482,7 @@
}
}
event.close();
+ */
}
} else {
throw new
IllegalStateException(sm.getString("standardWrapper.async.invalidContext"));
Modified: trunk/java/org/apache/catalina/deploy/FilterDef.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/FilterDef.java 2009-04-20 09:49:53 UTC (rev
1019)
+++ trunk/java/org/apache/catalina/deploy/FilterDef.java 2009-04-20 15:51:08 UTC (rev
1020)
@@ -130,12 +130,10 @@
* The set of initialization parameters for this filter, keyed by
* parameter name.
*/
- private Map parameters = new HashMap();
+ private Map<String, String> parameters = new HashMap<String, String>();
- public Map getParameterMap() {
-
+ public Map<String, String> getParameterMap() {
return (this.parameters);
-
}
@@ -164,9 +162,18 @@
* @param value The initialization parameter value
*/
public void addInitParameter(String name, String value) {
-
parameters.put(name, value);
+ }
+
+ /**
+ * Add an initialization parameter to the set of parameters associated
+ * with this filter.
+ *
+ * @param name The initialization parameter name
+ */
+ public String getInitParameter(String name) {
+ return parameters.get(name);
}
Modified: trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
===================================================================
--- trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java 2009-04-20 09:49:53 UTC
(rev 1019)
+++ trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java 2009-04-20 15:51:08 UTC
(rev 1020)
@@ -207,7 +207,7 @@
("htmlManagerServlet.deployUploadNoFile");
break;
}
- war = warUpload.getName();
+ war = warUpload.getFileName();
if (!war.toLowerCase().endsWith(".war")) {
message = sm.getString
("htmlManagerServlet.deployUploadNotWar",war);
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java 2009-04-20
09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java 2009-04-20
15:51:08 UTC (rev 1020)
@@ -202,7 +202,7 @@
*
* @return The original filename in the client's filesystem.
*/
- public String getName()
+ public String getFileName()
{
return fileName;
}
@@ -459,6 +459,12 @@
}
+ public String getName()
+ {
+ return fieldName;
+ }
+
+
/**
* Sets the field name used to reference this file item.
*
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java 2009-04-20 09:49:53
UTC (rev 1019)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java 2009-04-20 15:51:08
UTC (rev 1020)
@@ -127,6 +127,14 @@
/**
+ * Returns the original filename in the client's filesystem.
+ *
+ * @return The original filename in the client's filesystem.
+ */
+ String getFileName();
+
+
+ /**
* Returns the name of the field in the multipart form corresponding to
* this file item.
*