JBossWeb SVN: r1204 - in trunk/java/org/apache/catalina: connector and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-17 06:45:59 -0400 (Sat, 17 Oct 2009)
New Revision: 1204
Modified:
trunk/java/org/apache/catalina/Valve.java
trunk/java/org/apache/catalina/connector/LocalStrings.properties
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/StandardHostValve.java
trunk/java/org/apache/catalina/core/StandardWrapperValve.java
trunk/java/org/apache/catalina/valves/ValveBase.java
Log:
- Some valve javadoc update.
- Implement quite a few error conditions.
- Add error page processing to async.
Modified: trunk/java/org/apache/catalina/Valve.java
===================================================================
--- trunk/java/org/apache/catalina/Valve.java 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/Valve.java 2009-10-17 10:45:59 UTC (rev 1204)
@@ -136,7 +136,8 @@
* Process an event.
*
* @param request The servlet request to be processed
- * @param response The servlet response to be created
+ * @param response The servlet response to be processed
+ * @param event The event to be processed
*
* @exception IOException if an input/output error occurs, or is thrown
* by a subsequently invoked Valve, Filter, or Servlet
Modified: trunk/java/org/apache/catalina/connector/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/connector/LocalStrings.properties 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/connector/LocalStrings.properties 2009-10-17 10:45:59 UTC (rev 1204)
@@ -57,6 +57,9 @@
coyoteRequest.servletStack=Current Servlet stack for thread {0}
coyoteRequest.closed=Response has been closed already
coyoteRequest.logoutfail=Exception logging out user
+coyoteRequest.cannotStartAsync=Cannot start async
+coyoteRequest.onStartAsyncError=Error invoking onStartAsync on listener of class {0}
+coyoteRequest.dispatchNoServletContext=Could not determine or access context for server absolute path [{0}]
#
# MapperListener
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-10-17 10:45:59 UTC (rev 1204)
@@ -454,6 +454,12 @@
*/
protected String localName = null;
+
+ /**
+ * Can call startAsync.
+ */
+ protected boolean canStartAsync = true;
+
// --------------------------------------------------------- Public Methods
@@ -478,6 +484,7 @@
asyncContext = null;
asyncTimeout = 300000;
+ canStartAsync = true;
asyncListeners.clear();
authType = null;
inputBuffer.recycle();
@@ -843,6 +850,14 @@
}
+ public boolean getCanStartAsync() {
+ return canStartAsync;
+ }
+
+ public void setCanStartAsync(boolean canStartAsync) {
+ this.canStartAsync = canStartAsync;
+ }
+
// ------------------------------------------------- Request Public Methods
@@ -2183,6 +2198,9 @@
return (null);
return context.getServletContext();
}
+ public ServletContext getServletContext0() {
+ return getServletContext();
+ }
/**
@@ -3019,7 +3037,16 @@
if (CHECK_ASYNC && !isAsyncSupported()) {
throw new IllegalStateException(sm.getString("coyoteRequest.noAsync"));
}
- // FIXME: if (asyncContext != null && !processing) { throw ISE }
+ // ISE if response is closed
+ if (response.isClosed()) {
+ throw new IllegalStateException(sm.getString("coyoteRequest.closed"));
+ }
+ // ISE if this method is called again without any asynchronous dispatch
+ // ISE if called outside of the subsequent dispatch
+ // ISE if called again within the scope of the same dispatch
+ if (!canStartAsync) {
+ throw new IllegalStateException(sm.getString("coyoteRequest.cannotStartAsync"));
+ }
LinkedHashMap<AsyncListener, AsyncListenerRegistration> localAsyncListeners = asyncListeners;
asyncListeners = new LinkedHashMap<AsyncListener, AsyncListenerRegistration>();
for (AsyncListenerRegistration registration : localAsyncListeners.values()) {
@@ -3028,12 +3055,11 @@
try {
asyncListener.onStartAsync(asyncEvent);
} catch (IOException e) {
- // FIXME: error reporting ? throw new IllegalStateException(e);
+ throw new IllegalStateException(sm.getString("coyoteRequest.onStartAsyncError",
+ asyncListener.getClass().getName()), e);
}
}
- if (response.isClosed()) {
- throw new IllegalStateException(sm.getString("coyoteRequest.closed"));
- }
+ canStartAsync = false;
if (asyncContext == null) {
asyncContext = new AsyncContextImpl();
eventMode = true;
@@ -3104,13 +3130,7 @@
if (parts == null) {
parseMultipart();
}
- Part result = parts.get(name);
- if (result == null) {
- // FIXME: error message
- throw new ServletException();
- } else {
- return result;
- }
+ return parts.get(name);
}
@@ -3184,22 +3204,25 @@
}
public void dispatch() {
+ this.servletContext = null;
if (servletRequest == getRequestFacade()) {
// Get the path directly
path = getRequestPathMB().toString();
} else if (servletRequest instanceof HttpServletRequest) {
- // Rebuild the path
- path = ((HttpServletRequest) servletRequest).getRequestURI();
+ // Remap the path to the target context
+ String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
+ this.servletContext = getServletContext0().getContext(requestURI);
if (servletContext != null) {
- path = path.substring(servletContext.getContextPath().length());
+ path = requestURI.substring(servletContext.getContextPath().length());
} else {
- path = path.substring(context.getName().length());
+ throw new IllegalStateException(sm.getString("coyoteRequest.dispatchNoServletContext", requestURI));
}
}
resume();
}
public void dispatch(String path) {
+ this.servletContext = null;
this.path = path;
useAttributes = true;
resume();
Modified: trunk/java/org/apache/catalina/core/StandardHostValve.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardHostValve.java 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/core/StandardHostValve.java 2009-10-17 10:45:59 UTC (rev 1204)
@@ -37,6 +37,7 @@
import org.apache.catalina.valves.ValveBase;
import org.jboss.logging.Logger;
import org.jboss.servlet.http.HttpEvent;
+import org.jboss.servlet.http.HttpEvent.EventType;
/**
@@ -153,8 +154,8 @@
* Process Comet event.
*
* @param request Request to be processed
- * @param response Response to be produced
- * @param valveContext Valve context used to forward to the next Valve
+ * @param response Response to be processed
+ * @param event The event to be processed
*
* @exception IOException if an input/output error occurred
* @exception ServletException if a servlet error occurred
@@ -185,12 +186,27 @@
// Error page processing
response.setSuspended(false);
- Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
-
- if (t != null) {
- throwable(request, response, t);
+ if (request.getAsyncContext() == null) {
+ Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
+ if (t != null) {
+ throwable(request, response, t);
+ } else {
+ status(request, response);
+ }
} else {
- status(request, response);
+ Request.AsyncContextImpl asyncContext = (Request.AsyncContextImpl) request.getAsyncContext();
+ if ((event.getType() == EventType.TIMEOUT || event.getType() == EventType.ERROR)
+ && request.isEventMode() && asyncContext.getPath() == null) {
+ Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
+ if (t != null) {
+ throwable(request, response, t);
+ } else {
+ status(request, response);
+ }
+ }
+ if (request.isEventMode() && asyncContext.getPath() == null) {
+ asyncContext.complete();
+ }
}
// Restore the context classloader
Modified: trunk/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-10-17 10:45:59 UTC (rev 1204)
@@ -52,6 +52,7 @@
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
+import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.Servlet;
@@ -388,6 +389,7 @@
*
* @param request The servlet request to be processed
* @param response The servlet response to be created
+ * @param event The event to be processed
*
* @exception IOException if an input/output error occurs, or is thrown
* by a subsequently invoked Valve, Filter, or Servlet
@@ -398,105 +400,9 @@
throws IOException, ServletException {
// Async processing
- Request.AsyncContextImpl asyncContext = (Request.AsyncContextImpl) request.getAsyncContext();
+ AsyncContext asyncContext = request.getAsyncContext();
if (asyncContext != null) {
- if (event.getType() == EventType.END || event.getType() == EventType.ERROR
- || event.getType() == EventType.TIMEOUT) {
- // Invoke the listeners with onComplete or onTimeout
- boolean timeout = (event.getType() == EventType.TIMEOUT) ? true : false;
- boolean error = (event.getType() == EventType.ERROR) ? true : false;
- Iterator<AsyncListenerRegistration> asyncListenerRegistrations =
- asyncContext.getAsyncListeners().values().iterator();
- if (timeout && !asyncListenerRegistrations.hasNext()) {
- // FIXME: MUST do an ERROR dispatch to the original URI and MUST set the response code to 500
- }
- while (asyncListenerRegistrations.hasNext()) {
- AsyncListenerRegistration asyncListenerRegistration = asyncListenerRegistrations.next();
- AsyncListener asyncListener = asyncListenerRegistration.getListener();
- try {
- if (timeout) {
- AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
- asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse());
- asyncListener.onTimeout(asyncEvent);
- } else if (error) {
- Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
- AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
- asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse(), t);
- asyncListener.onError(asyncEvent);
- } else {
- AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
- asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse());
- asyncListener.onComplete(asyncEvent);
- }
- } catch (Throwable e) {
- container.getLogger().error(sm.getString("standardWrapper.async.listenerError",
- getContainer().getName()), e);
- exception(request, response, e);
- }
- }
- } else if (asyncContext.getRunnable() != null) {
- // Execute the runnable
- try {
- asyncContext.getRunnable().run();
- } catch (Throwable e) {
- container.getLogger().error(sm.getString("standardWrapper.async.runnableError",
- getContainer().getName()), e);
- 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();
- ServletContext servletContext = context.getServletContext();
- if (asyncContext.getServletContext() != null) {
- // Cross context
- servletContext = asyncContext.getServletContext();
- }
- ApplicationDispatcher dispatcher =
- (ApplicationDispatcher) servletContext.getRequestDispatcher(asyncContext.getPath());
- // Invoke the dispatcher async method with the attributes flag
- try {
- dispatcher.async(asyncContext.getRequest(), asyncContext.getResponse(),
- asyncContext.getUseAttributes());
- } catch (Throwable e) {
- container.getLogger().error(sm.getString("standardWrapper.async.dispatchError",
- getContainer().getName()), e);
- exception(request, response, e);
- // TODO: the exception must be sent to error
- }
- // 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 {
- // Close anyway
- try {
- PrintWriter writer = response.getWriter();
- writer.close();
- } catch (IllegalStateException e) {
- try {
- ServletOutputStream stream = response.getOutputStream();
- stream.close();
- } catch (IllegalStateException f) {
- ;
- } catch (IOException f) {
- ;
- }
- } catch (IOException e) {
- ;
- }
- }
- event.close();
- */
- }
- } else {
- throw new IllegalStateException(sm.getString("standardWrapper.async.invalidContext"));
- }
+ async(request, response, event);
return;
}
@@ -660,6 +566,99 @@
}
+ /**
+ * Process an async dispatch. This is never a direct wrapper invocation.
+ *
+ * @param request The servlet request to be processed
+ * @param response The servlet response to be processed
+ * @param event The event to be processed
+ *
+ * @exception IOException if an input/output error occurs, or is thrown
+ * by a subsequently invoked Valve, Filter, or Servlet
+ * @exception ServletException if a servlet error occurs, or is thrown
+ * by a subsequently invoked Valve, Filter, or Servlet
+ */
+ public void async(Request request, Response response, HttpEvent event)
+ throws IOException, ServletException {
+
+ Request.AsyncContextImpl asyncContext = (Request.AsyncContextImpl) request.getAsyncContext();
+ if (asyncContext != null) {
+ if (event.getType() == EventType.END || event.getType() == EventType.ERROR
+ || event.getType() == EventType.TIMEOUT) {
+ // Invoke the listeners with onComplete or onTimeout
+ boolean timeout = (event.getType() == EventType.TIMEOUT) ? true : false;
+ boolean error = (event.getType() == EventType.ERROR) ? true : false;
+ Iterator<AsyncListenerRegistration> asyncListenerRegistrations =
+ asyncContext.getAsyncListeners().values().iterator();
+ while (asyncListenerRegistrations.hasNext()) {
+ AsyncListenerRegistration asyncListenerRegistration = asyncListenerRegistrations.next();
+ AsyncListener asyncListener = asyncListenerRegistration.getListener();
+ try {
+ if (timeout) {
+ AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
+ asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse());
+ asyncListener.onTimeout(asyncEvent);
+ } else if (error) {
+ Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
+ AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
+ asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse(), t);
+ asyncListener.onError(asyncEvent);
+ } else {
+ AsyncEvent asyncEvent = new AsyncEvent(asyncContext,
+ asyncListenerRegistration.getRequest(), asyncListenerRegistration.getResponse());
+ asyncListener.onComplete(asyncEvent);
+ }
+ } catch (Throwable e) {
+ container.getLogger().error(sm.getString("standardWrapper.async.listenerError",
+ getContainer().getName()), e);
+ exception(request, response, e);
+ }
+ }
+ } else if (asyncContext.getRunnable() != null) {
+ // Execute the runnable
+ try {
+ asyncContext.getRunnable().run();
+ } catch (Throwable e) {
+ container.getLogger().error(sm.getString("standardWrapper.async.runnableError",
+ getContainer().getName()), e);
+ 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();
+ ServletContext servletContext = context.getServletContext();
+ if (asyncContext.getServletContext() != null) {
+ // Cross context
+ servletContext = asyncContext.getServletContext();
+ }
+ request.setCanStartAsync(true);
+ ApplicationDispatcher dispatcher =
+ (ApplicationDispatcher) servletContext.getRequestDispatcher(asyncContext.getPath());
+ // Invoke the dispatcher async method with the attributes flag
+ try {
+ dispatcher.async(asyncContext.getRequest(), asyncContext.getResponse(),
+ asyncContext.getUseAttributes());
+ } catch (Throwable e) {
+ container.getLogger().error(sm.getString("standardWrapper.async.dispatchError",
+ getContainer().getName()), e);
+ exception(request, response, e);
+ }
+ request.setCanStartAsync(false);
+ // If there is no new startAsync, then close the response
+ // Note: The spec uses the same asyncContext instance
+ if (!asyncContext.isReady()) {
+ asyncContext.complete();
+ }
+ } else {
+ throw new IllegalStateException(sm.getString("standardWrapper.async.invalidContext"));
+ }
+ }
+
+ }
+
// -------------------------------------------------------- Private Methods
Modified: trunk/java/org/apache/catalina/valves/ValveBase.java
===================================================================
--- trunk/java/org/apache/catalina/valves/ValveBase.java 2009-10-16 23:21:50 UTC (rev 1203)
+++ trunk/java/org/apache/catalina/valves/ValveBase.java 2009-10-17 10:45:59 UTC (rev 1204)
@@ -186,7 +186,8 @@
* the thread that is processing the request.
*
* @param request The servlet request to be processed
- * @param response The servlet response to be created
+ * @param response The servlet response to be processed
+ * @param event The event to be processed
*
* @exception IOException if an input/output error occurs, or is thrown
* by a subsequently invoked Valve, Filter, or Servlet
15 years, 2 months
JBossWeb SVN: r1203 - in trunk/java/org/apache/catalina: session and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 19:21:50 -0400 (Fri, 16 Oct 2009)
New Revision: 1203
Modified:
trunk/java/org/apache/catalina/core/StandardContext.java
trunk/java/org/apache/catalina/core/StandardContextValve.java
trunk/java/org/apache/catalina/session/StandardSession.java
Log:
- Listener order fix.
- Also add the request listener for event. Don't know if it really needs to be done, though.
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 17:30:49 UTC (rev 1202)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 23:21:50 UTC (rev 1203)
@@ -3918,16 +3918,15 @@
boolean ok = true;
Object listeners[] = getApplicationLifecycleListeners();
- if (listeners != null) {
+ if (listeners != null && (listeners.length > 0)) {
ServletContextEvent event =
new ServletContextEvent(getServletContext());
- for (int i = 0; i < listeners.length; i++) {
- int j = (listeners.length - 1) - i;
- if (listeners[j] == null)
+ for (int i = listeners.length - 1; i >= 0; i--) {
+ if (listeners[i] == null)
continue;
- if (listeners[j] instanceof ServletContextListener) {
+ if (listeners[i] instanceof ServletContextListener) {
ServletContextListener listener =
- (ServletContextListener) listeners[j];
+ (ServletContextListener) listeners[i];
try {
fireContainerEvent("beforeContextDestroyed", listener);
listener.contextDestroyed(event);
@@ -3936,16 +3935,16 @@
fireContainerEvent("afterContextDestroyed", listener);
getLogger().error
(sm.getString("standardContext.listenerStop",
- listeners[j].getClass().getName()), t);
+ listeners[i].getClass().getName()), t);
ok = false;
}
}
try {
- getInstanceManager().destroyInstance(listeners[j]);
+ getInstanceManager().destroyInstance(listeners[i]);
} catch (Throwable t) {
getLogger().error
(sm.getString("standardContext.listenerStop",
- listeners[j].getClass().getName()), t);
+ listeners[i].getClass().getName()), t);
ok = false;
}
}
@@ -3953,17 +3952,16 @@
// Annotation processing
listeners = getApplicationEventListeners();
- if (listeners != null) {
- for (int i = 0; i < listeners.length; i++) {
- int j = (listeners.length - 1) - i;
- if (listeners[j] == null)
+ if (listeners != null && (listeners.length > 0)) {
+ for (int i = listeners.length - 1; i >= 0; i--) {
+ if (listeners[i] == null)
continue;
try {
- getInstanceManager().destroyInstance(listeners[j]);
+ getInstanceManager().destroyInstance(listeners[i]);
} catch (Throwable t) {
getLogger().error
(sm.getString("standardContext.listenerStop",
- listeners[j].getClass().getName()), t);
+ listeners[i].getClass().getName()), t);
ok = false;
}
}
Modified: trunk/java/org/apache/catalina/core/StandardContextValve.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContextValve.java 2009-10-16 17:30:49 UTC (rev 1202)
+++ trunk/java/org/apache/catalina/core/StandardContextValve.java 2009-10-16 23:21:50 UTC (rev 1203)
@@ -193,7 +193,7 @@
if ((instances !=null ) &&
(instances.length > 0)) {
// create post-service event
- for (int i = 0; i < instances.length; i++) {
+ for (int i = instances.length - 1; i >= 0; i--) {
if (instances[i] == null)
continue;
if (!(instances[i] instanceof ServletRequestListener))
@@ -226,21 +226,12 @@
* @exception IOException if an input/output error occurred
* @exception ServletException if a servlet error occurred
*/
- public final void event(Request request, Response response, HttpEvent event)
+ public final void event(Request request, Response response, HttpEvent httpEvent)
throws IOException, ServletException {
- // Select the Wrapper to be used for this Request
- Wrapper wrapper = request.getWrapper();
-
- // Normal request processing
- // FIXME: This could be an addition to the core API too
- /*
Object instances[] = context.getApplicationEventListeners();
-
ServletRequestEvent event = null;
-
- if ((instances != null)
- && (instances.length > 0)) {
+ if (instances != null && (instances.length > 0)) {
event = new ServletRequestEvent
(((StandardContext) container).getServletContext(),
request.getRequest());
@@ -263,15 +254,14 @@
}
}
}
- */
- wrapper.getPipeline().getFirst().event(request, response, event);
+ // Select the Wrapper to be used for this Request
+ Wrapper wrapper = request.getWrapper();
+ wrapper.getPipeline().getFirst().event(request, response, httpEvent);
- /*
- if ((instances !=null ) &&
- (instances.length > 0)) {
+ if (instances != null && (instances.length > 0)) {
// create post-service event
- for (int i = 0; i < instances.length; i++) {
+ for (int i = instances.length - 1; i >= 0; i--) {
if (instances[i] == null)
continue;
if (!(instances[i] instanceof ServletRequestListener))
@@ -288,7 +278,6 @@
}
}
}
- */
}
Modified: trunk/java/org/apache/catalina/session/StandardSession.java
===================================================================
--- trunk/java/org/apache/catalina/session/StandardSession.java 2009-10-16 17:30:49 UTC (rev 1202)
+++ trunk/java/org/apache/catalina/session/StandardSession.java 2009-10-16 23:21:50 UTC (rev 1203)
@@ -670,18 +670,15 @@
expiring = true;
// Notify interested application event listeners
- // FIXME - Assumes we call listeners in reverse order
Context context = (Context) manager.getContainer();
Object listeners[] = context.getApplicationLifecycleListeners();
- if (notify && (listeners != null)) {
+ if (notify && listeners != null && (listeners.length > 0)) {
HttpSessionEvent event =
new HttpSessionEvent(getSession());
- for (int i = 0; i < listeners.length; i++) {
- int j = (listeners.length - 1) - i;
- if (!(listeners[j] instanceof HttpSessionListener))
+ for (int i = listeners.length - 1; i >= 0; i--) {
+ if (!(listeners[i] instanceof HttpSessionListener))
continue;
- HttpSessionListener listener =
- (HttpSessionListener) listeners[j];
+ HttpSessionListener listener = (HttpSessionListener) listeners[i];
try {
context.fireContainerEvent("beforeSessionDestroyed", listener);
listener.sessionDestroyed(event);
@@ -1606,9 +1603,9 @@
// Notify interested application event listeners
Context context = (Context) manager.getContainer();
Object listeners[] = context.getApplicationEventListeners();
- if (listeners == null)
+ if (listeners == null || (listeners.length < 1))
return;
- for (int i = 0; i < listeners.length; i++) {
+ for (int i = listeners.length - 1; i >= 0; i--) {
if (!(listeners[i] instanceof HttpSessionAttributeListener))
continue;
HttpSessionAttributeListener listener =
15 years, 2 months
JBossWeb SVN: r1202 - trunk/res/jboss/org/apache/catalina/startup.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 13:30:49 -0400 (Fri, 16 Oct 2009)
New Revision: 1202
Modified:
trunk/res/jboss/org/apache/catalina/startup/catalina.properties
Log:
- Allow cookie version switches.
Modified: trunk/res/jboss/org/apache/catalina/startup/catalina.properties
===================================================================
--- trunk/res/jboss/org/apache/catalina/startup/catalina.properties 2009-10-16 17:23:00 UTC (rev 1201)
+++ trunk/res/jboss/org/apache/catalina/startup/catalina.properties 2009-10-16 17:30:49 UTC (rev 1202)
@@ -11,7 +11,7 @@
org.apache.catalina.core.StandardHost.deployOnStartup=false
org.apache.catalina.core.StandardHost.deployXML=false
org.apache.catalina.core.StandardHost.startChildren=false
-org.apache.tomcat.util.http.ServerCookie.VERSION_SWITCH=false
+org.apache.tomcat.util.http.ServerCookie.VERSION_SWITCH=true
# String cache configuration.
org.apache.tomcat.util.buf.StringCache.byte.enabled=true
15 years, 2 months
JBossWeb SVN: r1201 - in trunk: res/jboss/org/apache/catalina/startup and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 13:23:00 -0400 (Fri, 16 Oct 2009)
New Revision: 1201
Modified:
trunk/java/org/apache/catalina/connector/Connector.java
trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
trunk/res/jboss/org/apache/catalina/startup/catalina.properties
Log:
- Take over the powered by header.
Modified: trunk/java/org/apache/catalina/connector/Connector.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Connector.java 2009-10-16 13:08:15 UTC (rev 1200)
+++ trunk/java/org/apache/catalina/connector/Connector.java 2009-10-16 17:23:00 UTC (rev 1201)
@@ -64,6 +64,10 @@
public static final boolean RECYCLE_FACADES =
Boolean.valueOf(System.getProperty("org.apache.catalina.connector.RECYCLE_FACADES", "false")).booleanValue();
+
+ protected static final boolean X_POWERED_BY =
+ Boolean.valueOf(System.getProperty("org.apache.catalina.connector.X_POWERED_BY", "false")).booleanValue();
+
// ------------------------------------------------------------ Constructor
@@ -115,10 +119,10 @@
protected boolean enableLookups = false;
- /*
+ /**
* Is generation of X-Powered-By response header enabled/disabled?
*/
- protected boolean xpoweredBy = false;
+ protected boolean xpoweredBy = X_POWERED_BY;
/**
Modified: trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
===================================================================
--- trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-10-16 13:08:15 UTC (rev 1200)
+++ trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-10-16 17:23:00 UTC (rev 1201)
@@ -90,6 +90,10 @@
Boolean.valueOf(System.getProperty("org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH", "false")).booleanValue();
+ protected static final String X_POWERED_BY =
+ System.getProperty("org.apache.catalina.connector.CoyoteAdapter.X_POWERED_BY", "Servlet/3.0; JBossWeb-3");
+
+
// ----------------------------------------------------------- Constructors
@@ -343,7 +347,7 @@
}
if (connector.getXpoweredBy()) {
- response.addHeader("X-Powered-By", "Servlet/3.0");
+ response.addHeader("X-Powered-By", X_POWERED_BY);
}
boolean event = false;
Modified: trunk/res/jboss/org/apache/catalina/startup/catalina.properties
===================================================================
--- trunk/res/jboss/org/apache/catalina/startup/catalina.properties 2009-10-16 13:08:15 UTC (rev 1200)
+++ trunk/res/jboss/org/apache/catalina/startup/catalina.properties 2009-10-16 17:23:00 UTC (rev 1201)
@@ -2,7 +2,9 @@
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
org.apache.catalina.core.StandardService.DELAY_CONNECTOR_STARTUP=true
org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
+org.apache.catalina.connector.Connector.X_POWERED_BY=true
org.apache.catalina.connector.Request.SESSION_ID_CHECK=true
+org.apache.catalina.connector.CoyoteAdapter.X_POWERED_BY=Servlet/3.0; JBossAS-6
org.apache.catalina.core.CONFIGBASE_MKDIRS=false
org.apache.catalina.core.StandardHost.autoDeploy=false
org.apache.catalina.core.StandardHost.configClass=org.jboss.web.tomcat.service.deployers.JBossContextConfig
15 years, 2 months
JBossWeb SVN: r1200 - tags.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 09:08:15 -0400 (Fri, 16 Oct 2009)
New Revision: 1200
Added:
tags/JBOSSWEB_3_0_0_ALPHA8/
Log:
- New alpha8 build.
Copied: tags/JBOSSWEB_3_0_0_ALPHA8 (from rev 1199, trunk)
15 years, 2 months
JBossWeb SVN: r1199 - trunk/java/org/apache/tomcat/util/http.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 09:02:04 -0400 (Fri, 16 Oct 2009)
New Revision: 1199
Modified:
trunk/java/org/apache/tomcat/util/http/ServerCookie.java
Log:
- Only v1 cookies can send comments, so for now switch versions if allowed and a comment is configured.
Modified: trunk/java/org/apache/tomcat/util/http/ServerCookie.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2009-10-16 10:34:28 UTC (rev 1198)
+++ trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2009-10-16 13:02:04 UTC (rev 1199)
@@ -290,7 +290,12 @@
buf.append( name );
buf.append("=");
// Servlet implementation does not check anything else
-
+
+ // Switch version if allowed and a comment has been configured
+ if (version == 0 && comment != null && VERSION_SWITCH) {
+ version = 1;
+ }
+
version = maybeQuote2(version, buf, value,true);
// Add version 1 specific information
15 years, 2 months
JBossWeb SVN: r1198 - trunk/java/org/apache/catalina/core.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 06:34:28 -0400 (Fri, 16 Oct 2009)
New Revision: 1198
Modified:
trunk/java/org/apache/catalina/core/ApplicationContext.java
trunk/java/org/apache/catalina/core/StandardContext.java
Log:
- Must also add the filter definition separately.
Modified: trunk/java/org/apache/catalina/core/ApplicationContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-10-16 10:01:59 UTC (rev 1197)
+++ trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-10-16 10:34:28 UTC (rev 1198)
@@ -873,6 +873,7 @@
FilterDef filterDef = new FilterDef();
filterDef.setFilterName(filterName);
filterDef.setFilterClass(className);
+ context.addFilterDef(filterDef);
ApplicationFilterConfig filterConfig = new ApplicationFilterConfig(context, filterDef);
filterConfig.setDynamic(true);
context.addApplicationFilterConfig(filterConfig);
@@ -891,6 +892,7 @@
FilterDef filterDef = new FilterDef();
filterDef.setFilterName(filterName);
filterDef.setFilterClass(filter.getClass().getName());
+ context.addFilterDef(filterDef);
ApplicationFilterConfig filterConfig = new ApplicationFilterConfig(context, filterDef);
filterConfig.setDynamic(true);
filterConfig.setFilter(filter);
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 10:01:59 UTC (rev 1197)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 10:34:28 UTC (rev 1198)
@@ -2310,10 +2310,8 @@
* @param filterDef The filter definition to be added
*/
public void addApplicationFilterConfig(ApplicationFilterConfig filterConfig) {
-
filterConfigs.put(filterConfig.getFilterName(), filterConfig);
fireContainerEvent("addApplicationFilterConfig", filterConfig);
-
}
15 years, 2 months
JBossWeb SVN: r1197 - in trunk/java/org/apache/catalina: core and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-16 06:01:59 -0400 (Fri, 16 Oct 2009)
New Revision: 1197
Modified:
trunk/java/org/apache/catalina/Context.java
trunk/java/org/apache/catalina/core/ApplicationContext.java
trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
trunk/java/org/apache/catalina/core/StandardContext.java
trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
Log:
- Add a dedicated "starting" flag, initialized is not the right thing (available was close, but not exactly it either).
Modified: trunk/java/org/apache/catalina/Context.java
===================================================================
--- trunk/java/org/apache/catalina/Context.java 2009-10-16 00:31:51 UTC (rev 1196)
+++ trunk/java/org/apache/catalina/Context.java 2009-10-16 10:01:59 UTC (rev 1197)
@@ -173,6 +173,20 @@
/**
+ * Return the application starting flag for this Context.
+ */
+ public boolean isStarting();
+
+
+ /**
+ * Set the application starting flag for this Context.
+ *
+ * @param starting The new application starting flag
+ */
+ public void setStarting(boolean starting);
+
+
+ /**
* Return the Locale to character set mapper for this Context.
*/
public CharsetMapper getCharsetMapper();
Modified: trunk/java/org/apache/catalina/core/ApplicationContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-10-16 00:31:51 UTC (rev 1196)
+++ trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-10-16 10:01:59 UTC (rev 1197)
@@ -866,7 +866,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -884,7 +884,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -913,7 +913,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -940,7 +940,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -1090,7 +1090,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.getAvailable()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(
sm.getString("applicationContext.setSessionTracking.ise",
getContextPath()));
@@ -1112,7 +1112,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -1124,7 +1124,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -1136,7 +1136,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -1156,7 +1156,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
@@ -1220,7 +1220,7 @@
if (restricted) {
throw new UnsupportedOperationException(sm.getString("applicationContext.restricted"));
}
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("applicationContext.alreadyInitialized",
getContextPath()));
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-10-16 00:31:51 UTC (rev 1196)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-10-16 10:01:59 UTC (rev 1197)
@@ -265,7 +265,7 @@
public boolean addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter, String... servletNames) {
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("filterRegistration.ise", context.getPath()));
}
if (servletNames == null || servletNames.length == 0) {
@@ -293,7 +293,7 @@
public boolean addMappingForUrlPatterns(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... urlPatterns) {
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("filterRegistration.ise", context.getPath()));
}
if (urlPatterns == null || urlPatterns.length == 0) {
@@ -357,7 +357,7 @@
public void setAsyncSupported(boolean asyncSupported) {
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("filterRegistration.ise", context.getPath()));
}
filterDef.setAsyncSupported(asyncSupported);
@@ -372,7 +372,7 @@
public boolean setInitParameter(String name, String value) {
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("filterRegistration.ise", context.getPath()));
}
if (name == null || value == null) {
@@ -388,7 +388,7 @@
public Set<String> setInitParameters(Map<String, String> initParameters) {
- if (context.isInitialized()) {
+ if (!context.isStarting()) {
throw new IllegalStateException(sm.getString("filterRegistration.ise", context.getPath()));
}
if (initParameters == null) {
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 00:31:51 UTC (rev 1196)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2009-10-16 10:01:59 UTC (rev 1197)
@@ -269,6 +269,11 @@
protected boolean available = false;
/**
+ * The application starting flag for this Context.
+ */
+ protected boolean starting = false;
+
+ /**
* The broadcaster that sends j2ee notifications.
*/
protected NotificationBroadcasterSupport broadcaster = null;
@@ -1084,6 +1089,24 @@
/**
+ * Return the application starting flag for this Context.
+ */
+ public boolean isStarting() {
+ return (this.starting);
+ }
+
+
+ /**
+ * Set the application starting flag for this Context.
+ *
+ * @param starting The new application starting flag
+ */
+ public void setStarting(boolean starting) {
+ this.starting = starting;
+ }
+
+
+ /**
* Return the Locale to character set mapper for this Context.
*/
public CharsetMapper getCharsetMapper() {
@@ -4130,6 +4153,7 @@
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
setAvailable(false);
+ setStarting(true);
setConfigured(false);
boolean ok = true;
@@ -4407,6 +4431,7 @@
}
setAvailable(false);
}
+ setStarting(false);
// JMX registration
registerJMX();
Modified: trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-10-16 00:31:51 UTC (rev 1196)
+++ trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-10-16 10:01:59 UTC (rev 1197)
@@ -154,7 +154,7 @@
public Set<String> addMapping(String... urlPatterns) {
Set<String> conflicts = new HashSet<String>();
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -173,7 +173,7 @@
public void setAsyncSupported(boolean asyncSupported) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -187,7 +187,7 @@
public boolean setInitParameter(String name, String value) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -204,7 +204,7 @@
public Set<String> setInitParameters(Map<String, String> initParameters) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -230,7 +230,7 @@
public void setLoadOnStartup(int loadOnStartup) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -273,7 +273,7 @@
}
public void setRunAsRole(String roleName) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -284,7 +284,7 @@
}
public void setServletSecurity(ServletSecurityElement servletSecurity) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
@@ -295,7 +295,7 @@
}
public void setMultipartConfig(MultipartConfigElement multipartConfig) {
- if (((Context) wrapper.getParent()).isInitialized()) {
+ if (!((Context) wrapper.getParent()).isStarting()) {
throw new IllegalStateException(sm.getString
("servletRegistration.ise", ((Context) wrapper.getParent()).getPath()));
}
15 years, 2 months
JBossWeb SVN: r1196 - in trunk/java/org/apache/catalina: core and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-15 20:31:51 -0400 (Thu, 15 Oct 2009)
New Revision: 1196
Modified:
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
Log:
- Fix the pointer and async check algorithm.
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-10-15 14:58:30 UTC (rev 1195)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-10-16 00:31:51 UTC (rev 1196)
@@ -2992,12 +2992,16 @@
ApplicationFilterChain filterChain = filterChains.get(i);
int n = filterChain.getFilterCount();
int pos = filterChain.getPointer();
- for (int j = 0; j < pos; j++) {
+ int lastFilter = pos;
+ if (pos == n + 1) {
+ lastFilter = n;
+ }
+ for (int j = 0; j < lastFilter; j++) {
if (!filterChain.getFilters()[j].getFilterDef().getAsyncSupported()) {
return false;
}
}
- if (pos == n) {
+ if (pos == n + 1) {
if (!filterChain.getWrapper().getAsyncSupported()) {
return false;
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterChain.java 2009-10-15 14:58:30 UTC (rev 1195)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterChain.java 2009-10-16 00:31:51 UTC (rev 1196)
@@ -252,6 +252,7 @@
// Call the next filter if there is one
if (pos < filterCount) {
ApplicationFilterConfig filterConfig = filters[pos++];
+ pointer++;
Filter filter = null;
try {
filter = filterConfig.getFilter();
@@ -275,22 +276,27 @@
support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
filter, request, response);
+ pointer--;
} catch (IOException e) {
+ pointer--;
if (filter != null)
support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
filter, request, response, e);
throw e;
} catch (ServletException e) {
+ pointer--;
if (filter != null)
support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
filter, request, response, e);
throw e;
} catch (RuntimeException e) {
+ pointer--;
if (filter != null)
support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
filter, request, response, e);
throw e;
} catch (Throwable e) {
+ pointer--;
if (filter != null)
support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
filter, request, response, e);
@@ -302,6 +308,7 @@
// We fell off the end of the chain -- call the servlet instance
Servlet servlet = wrapper.getServlet();
+ pointer++;
try {
if (Globals.STRICT_SERVLET_COMPLIANCE) {
lastServicedRequest.set(request);
@@ -352,6 +359,7 @@
throw new ServletException
(sm.getString("filterChain.servlet"), e);
} finally {
+ pointer--;
if (Globals.STRICT_SERVLET_COMPLIANCE) {
lastServicedRequest.set(null);
lastServicedResponse.set(null);
15 years, 2 months
JBossWeb SVN: r1195 - in trunk/java/org/apache: tomcat/util/http/fileupload and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-10-15 10:58:30 -0400 (Thu, 15 Oct 2009)
New Revision: 1195
Modified:
trunk/java/org/apache/catalina/connector/LocalStrings.properties
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/connector/RequestFacade.java
trunk/java/org/apache/tomcat/util/http/fileupload/DiskFileUpload.java
trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
Log:
- Implement the various error conditions for multipart, and fix a couple obvious problems.
Modified: trunk/java/org/apache/catalina/connector/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/connector/LocalStrings.properties 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/catalina/connector/LocalStrings.properties 2009-10-15 14:58:30 UTC (rev 1195)
@@ -48,6 +48,7 @@
coyoteRequest.listenerStop=Exception sending context destroyed event to listener instance of class {0}
coyoteRequest.attributeEvent=Exception thrown by attributes event listener
coyoteRequest.parseMultipart=Exception thrown whilst processing multipart
+coyoteRequest.notMultipart=The request is not multipart content
coyoteRequest.parseParameters=Exception thrown whilst processing POSTed parameters
coyoteRequest.postTooLarge=Parameters were not parsed because the size of the posted data was too big. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
coyoteRequest.noAuthenticator=No authenticator available for programmatic login
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-10-15 14:58:30 UTC (rev 1195)
@@ -112,6 +112,7 @@
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.fileupload.DiskFileUpload;
import org.apache.tomcat.util.http.fileupload.FileItem;
+import org.apache.tomcat.util.http.fileupload.FileUploadBase;
import org.apache.tomcat.util.http.mapper.MappingData;
@@ -2667,8 +2668,15 @@
}
if (!("application/x-www-form-urlencoded".equals(contentType))) {
// Check for multipart as an alternate way to send parameters
- if (parts == null) {
- parseMultipart();
+ if (parts == null && "multipart/form-data".equals(contentType)) {
+ try {
+ parseMultipart();
+ } catch (Exception e) {
+ if (context.getLogger().isDebugEnabled()) {
+ context.getLogger().debug(
+ sm.getString("coyoteRequest.parseMultipart"), e);
+ }
+ }
}
return;
}
@@ -2759,7 +2767,8 @@
/**
* Parse multipart.
*/
- protected void parseMultipart() {
+ protected void parseMultipart()
+ throws IOException, ServletException {
Multipart config = wrapper.getMultipartConfig();
if (config == null) {
@@ -2782,7 +2791,7 @@
contentType = contentType.trim();
}
if (!("multipart/form-data".equals(contentType)))
- return;
+ throw new ServletException(sm.getString("coyoteRequest.notMultipart"));
DiskFileUpload fu = new DiskFileUpload();
fu.setRepositoryPath(config.getLocation());
@@ -2798,21 +2807,16 @@
parts = new HashMap<String, Part>();
try {
- Iterator<FileItem> items = fu.parseRequest(getRequest()).iterator();
- while (items.hasNext()) {
- FileItem fileItem = items.next();
+ for (FileItem fileItem : fu.parseRequest(getRequest())) {
if (fileItem.getFileName() == null) {
coyoteRequest.getParameters().addParameterValues(fileItem.getName(), new String[] {fileItem.getString()});
}
- parts.put(fileItem.getFieldName(), fileItem);
+ parts.put(fileItem.getName(), fileItem);
}
- } catch (IOException e) {
- // Client disconnect
- if (context.getLogger().isDebugEnabled()) {
- context.getLogger().debug(
- sm.getString("coyoteRequest.parseMultipart"), e);
- }
- return;
+ } catch(FileUploadBase.FileSizeLimitExceededException e) {
+ throw new IllegalStateException(sm.getString("coyoteRequest.parseMultipart"), e);
+ } catch(FileUploadBase.SizeLimitExceededException e) {
+ throw new IllegalStateException(sm.getString("coyoteRequest.parseMultipart"), e);
}
}
@@ -3092,7 +3096,7 @@
}
- public Part getPart(String name) throws ServletException {
+ public Part getPart(String name) throws IOException, ServletException {
if (parts == null) {
parseMultipart();
}
@@ -3106,7 +3110,7 @@
}
- public Collection<Part> getParts() throws ServletException {
+ public Collection<Part> getParts() throws IOException, ServletException {
if (parts == null) {
parseMultipart();
}
Modified: trunk/java/org/apache/catalina/connector/RequestFacade.java
===================================================================
--- trunk/java/org/apache/catalina/connector/RequestFacade.java 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/catalina/connector/RequestFacade.java 2009-10-15 14:58:30 UTC (rev 1195)
@@ -1081,7 +1081,7 @@
}
- public Part getPart(String name) throws ServletException {
+ public Part getPart(String name) throws IOException, ServletException {
if (request == null) {
throw new IllegalStateException(
sm.getString("requestFacade.nullRequest"));
@@ -1091,7 +1091,7 @@
}
- public Collection<Part> getParts() throws ServletException {
+ public Collection<Part> getParts() throws IOException, ServletException {
if (request == null) {
throw new IllegalStateException(
sm.getString("requestFacade.nullRequest"));
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/DiskFileUpload.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/DiskFileUpload.java 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/DiskFileUpload.java 2009-10-15 14:58:30 UTC (rev 1195)
@@ -20,6 +20,7 @@
import java.io.File;
+import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -219,7 +220,7 @@
public List<FileItem> parseRequest(HttpServletRequest req,
int sizeThreshold,
long sizeMax, String path)
- throws FileUploadException
+ throws IOException, FileUploadException
{
setSizeThreshold(sizeThreshold);
setSizeMax(sizeMax);
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java 2009-10-15 14:58:30 UTC (rev 1195)
@@ -143,6 +143,11 @@
*/
private long sizeMax = -1;
+ /**
+ * The maximum size permitted for a single uploaded file, as opposed
+ * to {@link #sizeMax}. A value of -1 indicates no maximum.
+ */
+ private long fileSizeMax = -1;
/**
* The content encoding to use when reading part headers.
@@ -198,6 +203,28 @@
/**
+ * Returns the maximum allowed size of a single uploaded file,
+ * as opposed to {@link #getSizeMax()}.
+ *
+ * @see #setFileSizeMax(long)
+ * @return Maximum size of a single uploaded file.
+ */
+ public long getFileSizeMax() {
+ return fileSizeMax;
+ }
+
+ /**
+ * Sets the maximum allowed size of a single uploaded file,
+ * as opposed to {@link #getSizeMax()}.
+ *
+ * @see #getFileSizeMax()
+ * @param fileSizeMax Maximum size of a single uploaded file.
+ */
+ public void setFileSizeMax(long fileSizeMax) {
+ this.fileSizeMax = fileSizeMax;
+ }
+
+ /**
* Retrieves the character encoding used when reading the headers of an
* individual part. When not specified, or <code>null</code>, the platform
* default encoding is used.
@@ -240,7 +267,7 @@
* the request or storing files.
*/
public List<FileItem> parseRequest(HttpServletRequest req)
- throws FileUploadException
+ throws IOException, FileUploadException
{
if (null == req)
{
@@ -275,75 +302,47 @@
+ "it's size exceeds allowed range");
}
- try
+ int boundaryIndex = contentType.indexOf("boundary=");
+ if (boundaryIndex < 0)
{
- int boundaryIndex = contentType.indexOf("boundary=");
- if (boundaryIndex < 0)
- {
- throw new FileUploadException(
- "the request was rejected because "
- + "no multipart boundary was found");
- }
- byte[] boundary = contentType.substring(
- boundaryIndex + 9).getBytes();
+ throw new FileUploadException(
+ "the request was rejected because "
+ + "no multipart boundary was found");
+ }
+ byte[] boundary = contentType.substring(
+ boundaryIndex + 9).getBytes();
- InputStream input = req.getInputStream();
+ InputStream input = req.getInputStream();
- MultipartStream multi = new MultipartStream(input, boundary);
- multi.setHeaderEncoding(headerEncoding);
+ MultipartStream multi = new MultipartStream(input, boundary);
+ multi.setFileSizeMax(fileSizeMax);
+ multi.setHeaderEncoding(headerEncoding);
- boolean nextPart = multi.skipPreamble();
- while (nextPart)
+ boolean nextPart = multi.skipPreamble();
+ while (nextPart)
+ {
+ Map<String, String> headers = parseHeaders(multi.readHeaders());
+ String fieldName = getFieldName(headers);
+ if (fieldName != null)
{
- Map<String, String> headers = parseHeaders(multi.readHeaders());
- String fieldName = getFieldName(headers);
- if (fieldName != null)
+ String subContentType = getHeader(headers, CONTENT_TYPE);
+ if (subContentType != null && subContentType
+ .startsWith(MULTIPART_MIXED))
{
- String subContentType = getHeader(headers, CONTENT_TYPE);
- if (subContentType != null && subContentType
- .startsWith(MULTIPART_MIXED))
- {
- // Multiple files.
- byte[] subBoundary =
- subContentType.substring(
+ // Multiple files.
+ byte[] subBoundary =
+ subContentType.substring(
subContentType
.indexOf("boundary=") + 9).getBytes();
- multi.setBoundary(subBoundary);
- boolean nextSubPart = multi.skipPreamble();
- while (nextSubPart)
- {
- headers = parseHeaders(multi.readHeaders());
- if (getFileName(headers) != null)
- {
- FileItem item =
- createItem(headers, false);
- OutputStream os = item.getOutputStream();
- try
- {
- multi.readBodyData(os);
- }
- finally
- {
- os.close();
- }
- items.add(item);
- }
- else
- {
- // Ignore anything but files inside
- // multipart/mixed.
- multi.discardBodyData();
- }
- nextSubPart = multi.readBoundary();
- }
- multi.setBoundary(boundary);
- }
- else
+ multi.setBoundary(subBoundary);
+ boolean nextSubPart = multi.skipPreamble();
+ while (nextSubPart)
{
+ headers = parseHeaders(multi.readHeaders());
if (getFileName(headers) != null)
{
- // A single file.
- FileItem item = createItem(headers, false);
+ FileItem item =
+ createItem(headers, false);
OutputStream os = item.getOutputStream();
try
{
@@ -357,35 +356,55 @@
}
else
{
- // A form field.
- FileItem item = createItem(headers, true);
- OutputStream os = item.getOutputStream();
- try
- {
- multi.readBodyData(os);
- }
- finally
- {
- os.close();
- }
- items.add(item);
+ // Ignore anything but files inside
+ // multipart/mixed.
+ multi.discardBodyData();
}
+ nextSubPart = multi.readBoundary();
}
+ multi.setBoundary(boundary);
}
else
{
- // Skip this part.
- multi.discardBodyData();
+ if (getFileName(headers) != null)
+ {
+ // A single file.
+ FileItem item = createItem(headers, false);
+ OutputStream os = item.getOutputStream();
+ try
+ {
+ multi.readBodyData(os);
+ }
+ finally
+ {
+ os.close();
+ }
+ items.add(item);
+ }
+ else
+ {
+ // A form field.
+ FileItem item = createItem(headers, true);
+ OutputStream os = item.getOutputStream();
+ try
+ {
+ multi.readBodyData(os);
+ }
+ finally
+ {
+ os.close();
+ }
+ items.add(item);
+ }
}
- nextPart = multi.readBoundary();
}
+ else
+ {
+ // Skip this part.
+ multi.discardBodyData();
+ }
+ nextPart = multi.readBoundary();
}
- catch (IOException e)
- {
- throw new FileUploadException(
- "Processing of " + MULTIPART_FORM_DATA
- + " request failed. " + e.getMessage());
- }
return items;
}
@@ -639,4 +658,31 @@
}
}
+ /**
+ * Thrown to indicate that the request size exceeds the configured maximum.
+ */
+ public static class FileSizeLimitExceededException
+ extends FileUploadException
+ {
+ /**
+ * Constructs a <code>SizeExceededException</code> with no
+ * detail message.
+ */
+ public FileSizeLimitExceededException()
+ {
+ super();
+ }
+
+ /**
+ * Constructs an <code>SizeExceededException</code> with
+ * the specified detail message.
+ *
+ * @param message The detail message.
+ */
+ public FileSizeLimitExceededException(String message)
+ {
+ super(message);
+ }
+ }
+
}
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2009-10-15 14:57:00 UTC (rev 1194)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2009-10-15 14:58:30 UTC (rev 1195)
@@ -188,7 +188,10 @@
*/
private String headerEncoding;
+
+ private long fileSizeMax = -1;
+
// ----------------------------------------------------------- Constructors
@@ -261,7 +264,6 @@
*/
public MultipartStream(InputStream input,
byte[] boundary)
- throws IOException
{
this(input, boundary, DEFAULT_BUFSIZE);
}
@@ -269,6 +271,8 @@
// --------------------------------------------------------- Public methods
+
+
/**
* Retrieves the character encoding used when reading the headers of an
@@ -284,6 +288,16 @@
}
+ public long getFileSizeMax() {
+ return fileSizeMax;
+ }
+
+
+ public void setFileSizeMax(long fileSizeMax) {
+ this.fileSizeMax = fileSizeMax;
+ }
+
+
/**
* Specifies the character encoding to be used when reading the headers of
* individual parts. When not specified, or <code>null</code>, the platform
@@ -497,6 +511,9 @@
int total = 0;
while (!done)
{
+ if (fileSizeMax > 0 && total > fileSizeMax) {
+ throw new FileUploadBase.FileSizeLimitExceededException("File size exceeded");
+ }
// Is boundary token present somewere in the buffer?
pos = findSeparator();
if (pos != -1)
15 years, 2 months