You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2006/09/13 02:55:16 UTC
svn commit: r442778 - in /tomcat/tc6.0.x/trunk/java/org/apache/catalina: ./
connector/ core/ servlets/ valves/
Author: remm
Date: Tue Sep 12 17:55:15 2006
New Revision: 442778
URL: http://svn.apache.org/viewvc?view=rev&rev=442778
Log:
- Redo Comet processing using events.
- Add Valve.event (most regular valves do not do anything, but standard valves need to call the next pipeline).
- Add a new Filter interface that filters can implement to intercept the events (I didn't test it yet).
Added:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java (with props)
tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java (with props)
tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java (with props)
Removed:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometEvent.java Tue Sep 12 17:55:15 2006
@@ -41,7 +41,8 @@
* it is possible to use the response object to write data on the open connection.
* Note that the response object and depedent OutputStream and Writer are still
* not synchronized, so when they are accessed by multiple threads,
- * synchronization is mandatory.
+ * synchronization is mandatory. After processing the initial event, the request
+ * is considered to be committed.
* READ - This indicates that input data is available, and that one read can be made
* without blocking. The available and ready methods of the InputStream or
* Reader may be used to determine if there is a risk of blocking: the servlet
@@ -61,7 +62,7 @@
* been processed, the request and response objects, as well as all their dependent
* objects will be recycled and used to process other requests.
*/
- enum EventType {BEGIN, READ, END, ERROR}
+ public enum EventType {BEGIN, READ, END, ERROR}
/**
@@ -73,7 +74,7 @@
* SERVER_SHUTDOWN - the server is shutting down (sub type of END)
* SESSION_END - the servlet ended the session (sub type of END)
*/
- enum EventSubType { TIMEOUT, CLIENT_DISCONNECT, IOEXCEPTION, WEBAPP_RELOAD, SERVER_SHUTDOWN, SESSION_END }
+ public enum EventSubType { TIMEOUT, CLIENT_DISCONNECT, IOEXCEPTION, WEBAPP_RELOAD, SERVER_SHUTDOWN, SESSION_END }
/**
Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+
+/**
+ * The CometFilter interface.
+ *
+ * @author Filip Hanik
+ */
+public interface CometFilter {
+
+
+ public void doFilterEvent(CometEvent event, CometFilterChain chain) throws IOException, ServletException;
+
+
+}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+/**
+ * The CometFilter interface.
+ *
+ * @author Filip Hanik
+ */
+public interface CometFilterChain {
+
+
+ public void doFilterEvent(CometEvent event) throws IOException, ServletException;
+
+
+}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometFilterChain.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java Tue Sep 12 17:55:15 2006
@@ -20,8 +20,6 @@
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
/**
* This interface should be implemented by servlets which would like to handle
@@ -31,101 +29,13 @@
public interface CometProcessor {
/**
- * Begin will be called by the main service method of the servlet at the beginning
- * of the processing of the connection. It can be used to initialize any relevant
- * fields using the request and response objects. Between the end of the execution
- * of this method, and the beginning of the execution of the end or error methods,
- * it is possible to use the response object to write data on the open connection.
- * Note that the response object and depedent OutputStream and Writer are still
- * not synchronized, so when they are accessed by multiple threads,
- * synchronization is mandatory.
+ * Process the given Comet event.
*
- * @param request The HTTP servlet request instance, which can be accessed
- * asynchronously at any time until the end or error methods are called
- * @param response The HTTP servlet response instance, which can be accessed
- * asynchronously at any time until the end or error methods are called
- * @throws IOException An IOException may be thrown to indicate an IO error
- * @throws ServletException An exception has occurred, as specified by the root
- * cause
+ * @param event The Comet event that will be processed
+ * @throws IOException
+ * @throws ServletException
*/
- public void begin(HttpServletRequest request, HttpServletResponse response)
+ public void event(CometEvent event)
throws IOException, ServletException;
-
- /**
- * End may be called to end the processing of the request. Fields that have
- * been initialized in the begin method should be reset. After this method has
- * been called, the request and response objects, as well as all their dependent
- * objects will be recycled and used to process other requests.
- *
- * @param request The HTTP servlet request instance
- * @param response The HTTP servlet response instance
- * @throws IOException An IOException may be thrown to indicate an IO error
- * @throws ServletException An exception has occurred, as specified by the root
- * cause
- */
- public void end(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException;
-
- /**
- * Error will be called by the container in the case where an IO exception
- * or a similar unrecoverable error occurs on the connection. Fields that have
- * been initialized in the begin method should be reset. After this method has
- * been called, the request and response objects, as well as all their dependent
- * objects will be recycled and used to process other requests.
- *
- * @param request The HTTP servlet request instance
- * @param response The HTTP servlet response instance
- * @throws IOException An IOException may be thrown to indicate an IO error
- * @throws ServletException An exception has occurred, as specified by the root
- * cause
- */
- public void error(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException;
-
- /**
- * This indicates that input data is available, and that one read can be made
- * without blocking. The available and ready methods of the InputStream or
- * Reader may be used to determine if there is a risk of blocking: the servlet
- * should read while data is reported available, and can make one additional read
- * without blocking. When encountering a read error or an EOF, the servlet MUST
- * report it by either returning false or throwing an exception such as an
- * IOException. This will cause the error method to be invoked, and the connection
- * will be closed. It is not allowed to attempt reading data from the request object
- * outside of the execution of this method.
- *
- * @param request The HTTP servlet request instance
- * @param response The HTTP servlet response instance
- * @throws IOException An IOException may be thrown to indicate an IO error,
- * or that the EOF has been reached on the connection
- * @throws ServletException An exception has occurred, as specified by the root
- * cause
- * @return false if the read attempt returned an EOF; alternately, it is also
- * valid to throw an IOException
- */
- public boolean read(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException;
-
- /**
- * Sets the timeout for this Comet connection. Please NOTE, that the implementation
- * of a per connection timeout is OPTIONAL and MAY NOT be implemented.<br/>
- * This method sets the timeout in milliseconds of idle time on the connection.
- * The timeout is reset every time data is received from the connection or data is flushed
- * using <code>response.flushBuffer()</code>. If a timeout occurs, the
- * <code>error(HttpServletRequest, HttpServletResponse)</code> method is invoked. The
- * web application SHOULD NOT attempt to reuse the request and response objects after a timeout
- * as the <code>error(HttpServletRequest, HttpServletResponse)</code> method indicates.<br/>
- * This method should not be called asynchronously, as that will have no effect.
- * @param request The HTTP servlet request instance
- * @param response The HTTP servlet response instance
- * @param timeout The timeout in milliseconds for this connection, must be a positive value, larger than 0
- * @throws IOException An IOException may be thrown to indicate an IO error,
- * or that the EOF has been reached on the connection
- * @throws ServletException An exception has occurred, as specified by the root
- * cause
- * @throws UnsupportedOperationException if per connection timeout is not supported, either at all or at this phase
- * of the invocation.
- */
- public void setTimeout(HttpServletRequest request, HttpServletResponse response, int timeout)
- throws IOException, ServletException, UnsupportedOperationException;
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Valve.java Tue Sep 12 17:55:15 2006
@@ -128,5 +128,20 @@
public void invoke(Request request, Response response)
throws IOException, ServletException;
+
+ /**
+ * Process a Comet event.
+ *
+ * @param request The servlet request to be processed
+ * @param response The servlet response to be created
+ *
+ * @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 event(Request request, Response response, CometEvent event)
+ throws IOException, ServletException;
+
}
Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java?view=auto&rev=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java Tue Sep 12 17:55:15 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina.connector;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.CometEvent;
+
+public class CometEventImpl implements CometEvent {
+
+
+ public CometEventImpl(Request request, Response response) {
+ this.request = request;
+ this.response = response;
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * Associated request.
+ */
+ protected Request request = null;
+
+
+ /**
+ * Associated response.
+ */
+ protected Response response = null;
+
+
+ /**
+ * Event type.
+ */
+ protected EventType eventType = EventType.BEGIN;
+
+
+ /**
+ * Event sub type.
+ */
+ protected EventSubType eventSubType = null;
+
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Clear the event.
+ */
+ public void clear() {
+ request = null;
+ response = null;
+ }
+
+ public void setEventType(EventType eventType) {
+ this.eventType = eventType;
+ }
+
+ public void serEventSubType(EventSubType eventSubType) {
+ this.eventSubType = eventSubType;
+ }
+
+ public void close() throws IOException {
+ request.setComet(false);
+ response.finishResponse();
+ }
+
+ public EventSubType getEventSubType() {
+ return eventSubType;
+ }
+
+ public EventType getEventType() {
+ return eventType;
+ }
+
+ public HttpServletRequest getHttpServletRequest() {
+ return request.getRequest();
+ }
+
+ public HttpServletResponse getHttpServletResponse() {
+ return response.getResponse();
+ }
+
+ public void setTimeout(int timeout) throws IOException, ServletException,
+ UnsupportedOperationException {
+ if (request.getAttribute("org.apache.tomcat.comet.timeout.support") == Boolean.TRUE) {
+ request.setAttribute("org.apache.tomcat.comet.timeout", new Integer(timeout));
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}
Propchange: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CometEventImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Tue Sep 12 17:55:15 2006
@@ -21,6 +21,7 @@
import javax.servlet.Servlet;
+import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
@@ -119,29 +120,16 @@
if (request.getWrapper() != null) {
- CometProcessor servlet = null;
-
- // Bind the context CL to the current thread
- if (request.getContext().getLoader() != null ) {
- Thread.currentThread().setContextClassLoader
- (request.getContext().getLoader().getClassLoader());
- }
-
try {
- servlet = (CometProcessor) request.getWrapper().allocate();
if (error) {
- servlet.error(request.getRequest(), response.getResponse());
+ request.getEvent().setEventType(CometEvent.EventType.ERROR);
} else {
- if (!servlet.read(request.getRequest(), response.getResponse())) {
- error = true;
- try {
- servlet.error(request.getRequest(), response.getResponse());
- } catch (Throwable th) {
- log.error(sm.getString("coyoteAdapter.service"), th);
- }
- }
+ request.getEvent().setEventType(CometEvent.EventType.READ);
}
- if (response.isClosed()) {
+ // Calling the container
+ connector.getContainer().getPipeline().getFirst().event(request, response, request.getEvent());
+
+ if (response.isClosed() || !request.isComet()) {
res.action(ActionCode.ACTION_COMET_END, null);
}
return (!error);
@@ -150,24 +138,14 @@
log.error(sm.getString("coyoteAdapter.service"), t);
}
error = true;
- try {
- servlet.error(request.getRequest(), response.getResponse());
- } catch (Throwable th) {
- log.error(sm.getString("coyoteAdapter.service"), th);
- }
+ // FIXME: Since there's likely some structures kept in the servlet or elsewhere,
+ // a cleanup event of some sort could be needed ?
return false;
} finally {
- // Restore the context classloader
- Thread.currentThread().setContextClassLoader
- (CoyoteAdapter.class.getClassLoader());
- try {
- request.getWrapper().deallocate((Servlet) servlet);
- } catch (Exception e) {
- log.error(sm.getString("coyoteAdapter.service"), e);
- }
// Recycle the wrapper request and response
- if (error || response.isClosed()) {
+ if (error || response.isClosed() || !request.isComet()) {
request.recycle();
+ request.setFilterChain(null);
response.recycle();
}
}
@@ -223,11 +201,15 @@
// Calling the container
connector.getContainer().getPipeline().getFirst().invoke(request, response);
- if (request.getWrapper().getServlet() instanceof CometProcessor
- && !response.isClosed()
- && req.getAttribute("org.apache.tomcat.comet.support") == Boolean.TRUE) {
- comet = true;
- res.action(ActionCode.ACTION_COMET_BEGIN, null);
+ if (request.isComet()) {
+ if (!response.isClosed()) {
+ comet = true;
+ res.action(ActionCode.ACTION_COMET_BEGIN, null);
+ } else {
+ // Clear the filter chain, as otherwise it will not be reset elsewhere
+ // since this is a Comet request
+ request.setFilterChain(null);
+ }
}
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Request.java Tue Sep 12 17:55:15 2006
@@ -195,8 +195,20 @@
*/
protected String authType = null;
+
+ /**
+ * Associated event.
+ */
+ protected CometEventImpl event = null;
+
/**
+ * Comet state
+ */
+ protected boolean comet = false;
+
+
+ /**
* The current dispatcher type.
*/
protected Object dispatcherType = null;
@@ -373,6 +385,12 @@
dispatcherType = null;
requestDispatcherPath = null;
+ comet = false;
+ if (event != null) {
+ event.clear();
+ event = null;
+ }
+
authType = null;
inputBuffer.recycle();
usingInputStream = false;
@@ -2193,6 +2211,34 @@
}
+ /**
+ * Get the event associated with the request.
+ * @return
+ */
+ public CometEventImpl getEvent() {
+ if (event == null) {
+ event = new CometEventImpl(this, response);
+ }
+ return event;
+ }
+
+
+ /**
+ * Return true if the current request is handling Comet traffic.
+ */
+ public boolean isComet() {
+ return comet;
+ }
+
+
+ /**
+ * Set comet state.
+ */
+ public void setComet(boolean comet) {
+ this.comet = comet;
+ }
+
+
// ------------------------------------------------------ Protected Methods
@@ -2545,6 +2591,5 @@
}
}
-
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/Response.java Tue Sep 12 17:55:15 2006
@@ -481,13 +481,7 @@
public void finishResponse()
throws IOException {
// Writing leftover bytes
- try {
- outputBuffer.close();
- } catch(IOException e) {
- ;
- } catch(Throwable t) {
- t.printStackTrace();
- }
+ outputBuffer.close();
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterChain.java Tue Sep 12 17:55:15 2006
@@ -31,6 +31,10 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.CometEvent;
+import org.apache.catalina.CometFilter;
+import org.apache.catalina.CometFilterChain;
+import org.apache.catalina.CometProcessor;
import org.apache.catalina.InstanceEvent;
import org.apache.catalina.security.SecurityUtil;
import org.apache.catalina.util.InstanceSupport;
@@ -47,7 +51,7 @@
* @version $Revision: 303523 $ $Date: 2004-11-22 17:35:18 +0100 (lun., 22 nov. 2004) $
*/
-final class ApplicationFilterChain implements FilterChain {
+final class ApplicationFilterChain implements FilterChain, CometFilterChain {
// -------------------------------------------------------------- Constants
@@ -114,7 +118,7 @@
/**
* Static class array used when the SecurityManager is turned on and
- * <code>doFilter</code is invoked.
+ * <code>doFilter</code> is invoked.
*/
private static Class[] classType = new Class[]{ServletRequest.class,
ServletResponse.class,
@@ -122,12 +126,26 @@
/**
* Static class array used when the SecurityManager is turned on and
- * <code>service</code is invoked.
+ * <code>service</code> is invoked.
*/
private static Class[] classTypeUsedInService = new Class[]{
ServletRequest.class,
ServletResponse.class};
+ /**
+ * Static class array used when the SecurityManager is turned on and
+ * <code>doFilterEvent</code> is invoked.
+ */
+ private static Class[] cometClassType =
+ new Class[]{ CometEvent.class, CometFilterChain.class};
+
+ /**
+ * Static class array used when the SecurityManager is turned on and
+ * <code>event</code> is invoked.
+ */
+ private static Class[] classTypeUsedInEvent =
+ new Class[] { CometEvent.class };
+
// ---------------------------------------------------- FilterChain Methods
@@ -279,6 +297,163 @@
}
+ /**
+ * Invoke the next filter in this chain, passing the specified request
+ * and response. If there are no more filters in this chain, invoke
+ * the <code>service()</code> method of the servlet itself.
+ *
+ * @param request The servlet request we are processing
+ * @param response The servlet response we are creating
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a servlet exception occurs
+ */
+ public void doFilterEvent(CometEvent event)
+ throws IOException, ServletException {
+
+ if( System.getSecurityManager() != null ) {
+ final CometEvent ev = event;
+ try {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedExceptionAction() {
+ public Object run()
+ throws ServletException, IOException {
+ internalDoFilterEvent(ev);
+ return null;
+ }
+ }
+ );
+ } catch( PrivilegedActionException pe) {
+ Exception e = pe.getException();
+ if (e instanceof ServletException)
+ throw (ServletException) e;
+ else if (e instanceof IOException)
+ throw (IOException) e;
+ else if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ else
+ throw new ServletException(e.getMessage(), e);
+ }
+ } else {
+ internalDoFilterEvent(event);
+ }
+ }
+
+ private void internalDoFilterEvent(CometEvent event)
+ throws IOException, ServletException {
+
+ // Call the next filter if there is one
+ if (pos < n) {
+ ApplicationFilterConfig filterConfig = filters[pos++];
+ CometFilter filter = null;
+ try {
+ filter = (CometFilter) filterConfig.getFilter();
+ // FIXME: No instance listener processing for events for now
+ /*
+ support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
+ filter, event);
+ */
+
+ if( System.getSecurityManager() != null ) {
+ final CometEvent ev = event;
+ Principal principal =
+ ev.getHttpServletRequest().getUserPrincipal();
+
+ Object[] args = new Object[]{ev, this};
+ SecurityUtil.doAsPrivilege
+ ("doFilterEvent", (Filter) filter, cometClassType, args);
+
+ args = null;
+ } else {
+ filter.doFilterEvent(event, this);
+ }
+
+ /*support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+ filter, event);*/
+ } catch (IOException e) {
+ /*
+ if (filter != null)
+ support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+ filter, event, e);
+ */
+ throw e;
+ } catch (ServletException e) {
+ /*
+ if (filter != null)
+ support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+ filter, event, e);
+ */
+ throw e;
+ } catch (RuntimeException e) {
+ /*
+ if (filter != null)
+ support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+ filter, event, e);
+ */
+ throw e;
+ } catch (Throwable e) {
+ /*if (filter != null)
+ support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
+ filter, event, e);*/
+ throw new ServletException
+ (sm.getString("filterChain.filter"), e);
+ }
+ return;
+ }
+
+ // We fell off the end of the chain -- call the servlet instance
+ try {
+ /*
+ support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
+ servlet, request, response);
+ */
+ if( System.getSecurityManager() != null ) {
+ final CometEvent ev = event;
+ Principal principal =
+ ev.getHttpServletRequest().getUserPrincipal();
+ Object[] args = new Object[]{ ev };
+ SecurityUtil.doAsPrivilege("event",
+ servlet,
+ classTypeUsedInEvent,
+ args,
+ principal);
+ args = null;
+ } else {
+ ((CometProcessor) servlet).event(event);
+ }
+ /*
+ support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+ servlet, request, response);*/
+ } catch (IOException e) {
+ /*
+ support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+ servlet, request, response, e);
+ */
+ throw e;
+ } catch (ServletException e) {
+ /*
+ support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+ servlet, request, response, e);
+ */
+ throw e;
+ } catch (RuntimeException e) {
+ /*
+ support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+ servlet, request, response, e);
+ */
+ throw e;
+ } catch (Throwable e) {
+ /*
+ support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
+ servlet, request, response, e);
+ */
+ throw new ServletException
+ (sm.getString("filterChain.servlet"), e);
+ }
+
+ }
+
+
// -------------------------------------------------------- Package Methods
@@ -311,6 +486,14 @@
servlet = null;
support = null;
+ }
+
+
+ /**
+ * Prepare for reuse of the filters and wrapper executed by this chain.
+ */
+ void reuse() {
+ pos = 0;
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java Tue Sep 12 17:55:15 2006
@@ -22,6 +22,7 @@
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
+import org.apache.catalina.CometFilter;
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Request;
@@ -118,6 +119,8 @@
if (servlet == null)
return (null);
+ boolean comet = false;
+
// Create and initialize a filter chain object
ApplicationFilterChain filterChain = null;
if ((securityManager == null) && (request instanceof Request)) {
@@ -127,6 +130,7 @@
filterChain = new ApplicationFilterChain();
req.setFilterChain(filterChain);
}
+ comet = req.isComet();
} else {
// Security: Do not recycle
filterChain = new ApplicationFilterChain();
@@ -148,8 +152,6 @@
// Acquire the information we will need to match filter mappings
String servletName = wrapper.getName();
- int n = 0;
-
// Add the relevant path-mapped filters to this filter chain
for (int i = 0; i < filterMaps.length; i++) {
if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
@@ -163,8 +165,21 @@
; // FIXME - log configuration problem
continue;
}
- filterChain.addFilter(filterConfig);
- n++;
+ boolean isCometFilter = false;
+ if (comet) {
+ try {
+ isCometFilter = filterConfig.getFilter() instanceof CometFilter;
+ } catch (Exception e) {
+ // Note: The try catch is there because getFilter has a lot of
+ // declared exceptions. However, the filter is allocated much
+ // earlier
+ }
+ if (isCometFilter) {
+ filterChain.addFilter(filterConfig);
+ }
+ } else {
+ filterChain.addFilter(filterConfig);
+ }
}
// Add filters that match on servlet name second
@@ -180,8 +195,21 @@
; // FIXME - log configuration problem
continue;
}
- filterChain.addFilter(filterConfig);
- n++;
+ boolean isCometFilter = false;
+ if (comet) {
+ try {
+ isCometFilter = filterConfig.getFilter() instanceof CometFilter;
+ } catch (Exception e) {
+ // Note: The try catch is there because getFilter has a lot of
+ // declared exceptions. However, the filter is allocated much
+ // earlier
+ }
+ if (isCometFilter) {
+ filterChain.addFilter(filterConfig);
+ }
+ } else {
+ filterChain.addFilter(filterConfig);
+ }
}
// Return the completed filter chain
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Tue Sep 12 17:55:15 2006
@@ -4473,15 +4473,15 @@
try {
- // Stop our filters
- filterStop();
-
// Stop our child containers, if any
Container[] children = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).stop();
}
+
+ // Stop our filters
+ filterStop();
// Stop our application listeners
listenerStop();
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContextValve.java Tue Sep 12 17:55:15 2006
@@ -26,6 +26,7 @@
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.CometEvent;
import org.apache.catalina.Container;
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
@@ -33,8 +34,6 @@
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.valves.ValveBase;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.buf.MessageBytes;
/**
@@ -69,9 +68,6 @@
StringManager.getManager(Constants.Package);
- private static Log log = LogFactory.getLog(StandardContextValve.class);
-
-
private StandardContext context = null;
@@ -198,6 +194,85 @@
}
}
+ }
+
+
+ /**
+ * Select the appropriate child Wrapper to process this request,
+ * based on the specified request URI. If no matching Wrapper can
+ * be found, return an appropriate HTTP error.
+ *
+ * @param request Request to be processed
+ * @param response Response to be produced
+ * @param valveContext Valve context used to forward to the next Valve
+ *
+ * @exception IOException if an input/output error occurred
+ * @exception ServletException if a servlet error occurred
+ */
+ public final void event(Request request, Response response, CometEvent event)
+ 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)) {
+ event = new ServletRequestEvent
+ (((StandardContext) container).getServletContext(),
+ request.getRequest());
+ // create pre-service event
+ for (int i = 0; i < instances.length; i++) {
+ if (instances[i] == null)
+ continue;
+ if (!(instances[i] instanceof ServletRequestListener))
+ continue;
+ ServletRequestListener listener =
+ (ServletRequestListener) instances[i];
+ try {
+ listener.requestInitialized(event);
+ } catch (Throwable t) {
+ container.getLogger().error(sm.getString("requestListenerValve.requestInit",
+ instances[i].getClass().getName()), t);
+ ServletRequest sreq = request.getRequest();
+ sreq.setAttribute(Globals.EXCEPTION_ATTR,t);
+ return;
+ }
+ }
+ }
+ */
+
+ wrapper.getPipeline().getFirst().event(request, response, event);
+
+ /*
+ if ((instances !=null ) &&
+ (instances.length > 0)) {
+ // create post-service event
+ for (int i = 0; i < instances.length; i++) {
+ if (instances[i] == null)
+ continue;
+ if (!(instances[i] instanceof ServletRequestListener))
+ continue;
+ ServletRequestListener listener =
+ (ServletRequestListener) instances[i];
+ try {
+ listener.requestDestroyed(event);
+ } catch (Throwable t) {
+ container.getLogger().error(sm.getString("requestListenerValve.requestDestroy",
+ instances[i].getClass().getName()), t);
+ ServletRequest sreq = request.getRequest();
+ sreq.setAttribute(Globals.EXCEPTION_ATTR,t);
+ }
+ }
+ }
+ */
+
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardEngineValve.java Tue Sep 12 17:55:15 2006
@@ -23,6 +23,7 @@
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.CometEvent;
import org.apache.catalina.Host;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
@@ -105,6 +106,25 @@
// Ask this Host to process this request
host.getPipeline().getFirst().invoke(request, response);
+
+ }
+
+
+ /**
+ * 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
+ *
+ * @exception IOException if an input/output error occurred
+ * @exception ServletException if a servlet error occurred
+ */
+ public final void event(Request request, Response response, CometEvent event)
+ throws IOException, ServletException {
+
+ // Ask this Host to process this request
+ request.getHost().getPipeline().getFirst().event(request, response, event);
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardHostValve.java Tue Sep 12 17:55:15 2006
@@ -25,6 +25,7 @@
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.CometEvent;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
@@ -124,6 +125,57 @@
// Ask this Context to process this request
context.getPipeline().getFirst().invoke(request, response);
+
+ // Access a session (if present) to update last accessed time, based on a
+ // strict interpretation of the specification
+ if (Globals.STRICT_SERVLET_COMPLIANCE) {
+ request.getSession(false);
+ }
+
+ // Error page processing
+ response.setSuspended(false);
+
+ Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
+
+ if (t != null) {
+ throwable(request, response, t);
+ } else {
+ status(request, response);
+ }
+
+ // Restore the context classloader
+ Thread.currentThread().setContextClassLoader
+ (StandardHostValve.class.getClassLoader());
+
+ }
+
+
+ /**
+ * 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
+ *
+ * @exception IOException if an input/output error occurred
+ * @exception ServletException if a servlet error occurred
+ */
+ public final void event(Request request, Response response, CometEvent event)
+ throws IOException, ServletException {
+
+ // Select the Context to be used for this Request
+ Context context = request.getContext();
+
+ // Bind the context CL to the current thread
+ if( context.getLoader() != null ) {
+ // Not started - it should check for availability first
+ // This should eventually move to Engine, it's generic.
+ Thread.currentThread().setContextClassLoader
+ (context.getLoader().getClassLoader());
+ }
+
+ // Ask this Context to process this request
+ context.getPipeline().getFirst().event(request, response, event);
// Access a session (if present) to update last accessed time, based on a
// strict interpretation of the specification
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java Tue Sep 12 17:55:15 2006
@@ -27,6 +27,8 @@
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.CometEvent;
+import org.apache.catalina.CometProcessor;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.connector.ClientAbortException;
@@ -155,6 +157,12 @@
servlet = null;
}
+ // Identify if the request is Comet related now that the servlet has been allocated
+ if (servlet instanceof CometProcessor
+ && request.getAttribute("org.apache.tomcat.comet.support") == Boolean.TRUE) {
+ request.setComet(true);
+ }
+
// Acknowlege the request
try {
response.sendAcknowledgement();
@@ -196,13 +204,16 @@
else
request.removeAttribute(Globals.JSP_FILE_ATTR);
if ((servlet != null) && (filterChain != null)) {
-
// Swallow output if needed
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
- filterChain.doFilter(request.getRequest(),
- response.getResponse());
+ if (request.isComet()) {
+ filterChain.doFilterEvent(request.getEvent());
+ } else {
+ filterChain.doFilter(request.getRequest(),
+ response.getResponse());
+ }
} finally {
String log = SystemLogHandler.stopCapture();
if (log != null && log.length() > 0) {
@@ -210,8 +221,12 @@
}
}
} else {
- filterChain.doFilter
- (request.getRequest(), response.getResponse());
+ if (request.isComet()) {
+ filterChain.doFilterEvent(request.getEvent());
+ } else {
+ filterChain.doFilter
+ (request.getRequest(), response.getResponse());
+ }
}
}
@@ -264,11 +279,23 @@
}
// Release the filter chain (if any) for this request
- try {
- if (filterChain != null)
+ if (filterChain != null) {
+ if (request.isComet()) {
+ // If this is a Comet request, then the same chain will be used for the
+ // processing of all subsequent events.
+ filterChain.reuse();
+ } else {
filterChain.release();
+ }
+ }
+
+ // Deallocate the allocated servlet instance
+ try {
+ if (servlet != null) {
+ wrapper.deallocate(servlet);
+ }
} catch (Throwable e) {
- container.getLogger().error(sm.getString("standardWrapper.releaseFilters",
+ container.getLogger().error(sm.getString("standardWrapper.deallocateException",
wrapper.getName()), e);
if (throwable == null) {
throwable = e;
@@ -276,6 +303,159 @@
}
}
+ // If this servlet has been marked permanently unavailable,
+ // unload it and release this instance
+ try {
+ if ((servlet != null) &&
+ (wrapper.getAvailable() == Long.MAX_VALUE)) {
+ wrapper.unload();
+ }
+ } catch (Throwable e) {
+ container.getLogger().error(sm.getString("standardWrapper.unloadException",
+ wrapper.getName()), e);
+ if (throwable == null) {
+ throwable = e;
+ exception(request, response, e);
+ }
+ }
+ long t2=System.currentTimeMillis();
+
+ long time=t2-t1;
+ processingTime += time;
+ if( time > maxTime) maxTime=time;
+ if( time < minTime) minTime=time;
+
+ }
+
+
+ /**
+ * Process a Comet event. The main differences here are to not use sendError
+ * (the response is committed), to avoid creating a new filter chain
+ * (which would work but be pointless), and a few very minor tweaks.
+ *
+ * @param request The servlet request to be processed
+ * @param response The servlet response to be created
+ *
+ * @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 event(Request request, Response response, CometEvent event)
+ throws IOException, ServletException {
+
+ // Initialize local variables we may need
+ Throwable throwable = null;
+ // This should be a Request attribute...
+ long t1=System.currentTimeMillis();
+ // FIXME: Add a flag to count the total amount of events processed ? requestCount++;
+ StandardWrapper wrapper = (StandardWrapper) getContainer();
+ Servlet servlet = null;
+ Context context = (Context) wrapper.getParent();
+
+ // Check for the application being marked unavailable
+ boolean unavailable = !context.getAvailable() || wrapper.isUnavailable();
+
+ // Allocate a servlet instance to process this request
+ try {
+ if (!unavailable) {
+ servlet = wrapper.allocate();
+ }
+ } catch (UnavailableException e) {
+ // The response is already committed, so it's not possible to do anything
+ } catch (ServletException e) {
+ container.getLogger().error(sm.getString("standardWrapper.allocateException",
+ wrapper.getName()), StandardWrapper.getRootCause(e));
+ throwable = e;
+ exception(request, response, e);
+ servlet = null;
+ } catch (Throwable e) {
+ container.getLogger().error(sm.getString("standardWrapper.allocateException",
+ wrapper.getName()), e);
+ throwable = e;
+ exception(request, response, e);
+ servlet = null;
+ }
+
+ MessageBytes requestPathMB = null;
+ if (request != null) {
+ requestPathMB = request.getRequestPathMB();
+ }
+ request.setAttribute
+ (ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
+ ApplicationFilterFactory.REQUEST_INTEGER);
+ request.setAttribute
+ (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
+ requestPathMB);
+ // Get the current (unchanged) filter chain for this request
+ ApplicationFilterChain filterChain =
+ (ApplicationFilterChain) request.getFilterChain();
+
+ // Call the filter chain for this request
+ // NOTE: This also calls the servlet's event() method
+ try {
+ String jspFile = wrapper.getJspFile();
+ if (jspFile != null)
+ request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
+ else
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ if ((servlet != null) && (filterChain != null)) {
+
+ // Swallow output if needed
+ if (context.getSwallowOutput()) {
+ try {
+ SystemLogHandler.startCapture();
+ filterChain.doFilterEvent(request.getEvent());
+ } finally {
+ String log = SystemLogHandler.stopCapture();
+ if (log != null && log.length() > 0) {
+ context.getLogger().info(log);
+ }
+ }
+ } else {
+ filterChain.doFilterEvent(request.getEvent());
+ }
+
+ }
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ } catch (ClientAbortException e) {
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ throwable = e;
+ exception(request, response, e);
+ } catch (IOException e) {
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ container.getLogger().warn(sm.getString("standardWrapper.serviceException",
+ wrapper.getName()), e);
+ throwable = e;
+ exception(request, response, e);
+ } catch (UnavailableException e) {
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ container.getLogger().warn(sm.getString("standardWrapper.serviceException",
+ wrapper.getName()), e);
+ // Do not save exception in 'throwable', because we
+ // do not want to do exception(request, response, e) processing
+ } catch (ServletException e) {
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ Throwable rootCause = StandardWrapper.getRootCause(e);
+ if (!(rootCause instanceof ClientAbortException)) {
+ container.getLogger().error(sm.getString("standardWrapper.serviceException",
+ wrapper.getName()), rootCause);
+ }
+ throwable = e;
+ exception(request, response, e);
+ } catch (Throwable e) {
+ request.removeAttribute(Globals.JSP_FILE_ATTR);
+ container.getLogger().error(sm.getString("standardWrapper.serviceException",
+ wrapper.getName()), e);
+ throwable = e;
+ exception(request, response, e);
+ }
+
+ // Release the filter chain (if any) for this request
+ if (filterChain != null) {
+ filterChain.reuse();
+ }
+
// Deallocate the allocated servlet instance
try {
if (servlet != null) {
@@ -305,6 +485,7 @@
exception(request, response, e);
}
}
+
long t2=System.currentTimeMillis();
long time=t2-t1;
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java?view=diff&rev=442778&r1=442777&r2=442778
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ValveBase.java Tue Sep 12 17:55:15 2006
@@ -26,6 +26,7 @@
import javax.management.ObjectName;
import javax.servlet.ServletException;
+import org.apache.catalina.CometEvent;
import org.apache.catalina.Contained;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
@@ -177,6 +178,26 @@
*/
public abstract void invoke(Request request, Response response)
throws IOException, ServletException;
+
+
+ /**
+ * Process a Comet event. This method will rarely need to be provided by
+ * a subclass, unless it needs to reassociate a particular object with
+ * the thread that is processing the request.
+ *
+ * @param request The servlet request to be processed
+ * @param response The servlet response to be created
+ *
+ * @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 event(Request request, Response response, CometEvent event)
+ throws IOException, ServletException {
+ // Perform the request
+ getNext().event(request, response, event);
+ }
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org