Author: markt Date: Thu Feb 11 21:39:35 2016 New Revision: 1729896 URL: http://svn.apache.org/viewvc?rev=1729896&view=rev Log: Add the ability for Tomcat internal components, mainly Valves, to wrap the request and response that will be passed to the application.
Modified: tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/catalina/connector/Response.java Modified: tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties?rev=1729896&r1=1729895&r2=1729896&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties Thu Feb 11 21:39:35 2016 @@ -70,9 +70,11 @@ inputBuffer.requiresNonBlocking=Not avai outputBuffer.writeNull=The String argument to write(String,int,int) may not be null request.asyncNotSupported=A filter or servlet of the current chain does not support asynchronous operations. +request.illegalWrap=The request wrapper must wrap the request obtained from getRequest() requestFacade.nullRequest=The request object has been recycled and is no longer associated with this facade +response.illegalWrap=The response wrapper must wrap the response obtained from getResponse() response.sendRedirectFail=Failed to redirect to [{0}] responseFacade.nullResponse=The response object has been recycled and is no longer associated with this facade Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1729896&r1=1729895&r2=1729896&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Thu Feb 11 21:39:35 2016 @@ -59,6 +59,7 @@ import javax.servlet.ServletResponse; import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpUpgradeHandler; @@ -412,6 +413,8 @@ public class Request implements HttpServ protected Boolean asyncSupported = null; + private HttpServletRequest applicationRequest = null; + // --------------------------------------------------------- Public Methods @@ -480,6 +483,7 @@ public class Request implements HttpServ mappingData.recycle(); + applicationRequest = null; if (Globals.IS_SECURITY_ENABLED || Connector.RECYCLE_FACADES) { if (facade != null) { facade.clear(); @@ -630,6 +634,7 @@ public class Request implements HttpServ */ protected RequestFacade facade = null; + /** * @return the <code>ServletRequest</code> for which this object * is the facade. This method must be implemented by a subclass. @@ -638,7 +643,31 @@ public class Request implements HttpServ if (facade == null) { facade = new RequestFacade(this); } - return facade; + if (applicationRequest == null) { + applicationRequest = facade; + } + return applicationRequest; + } + + + /** + * Set a wrapped HttpServletRequest to pass to the application. Components + * wishing to wrap the request should obtain the request via + * {@link #getRequest()}, wrap it and then call this method with the + * wrapped request. + * + * @param applicationRequest The wrapped request to pass to the application + */ + public void setRequest(HttpServletRequest applicationRequest) { + // Check the wrapper wraps this request + ServletRequest r = applicationRequest; + while (r instanceof HttpServletRequestWrapper) { + r = ((HttpServletRequestWrapper) r).getRequest(); + } + if (r != facade) { + throw new IllegalArgumentException(sm.getString("request.illegalWrap")); + } + this.applicationRequest = applicationRequest; } Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1729896&r1=1729895&r2=1729896&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Thu Feb 11 21:39:35 2016 @@ -38,9 +38,11 @@ import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.ServletOutputStream; +import javax.servlet.ServletResponse; import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; import org.apache.catalina.Context; import org.apache.catalina.Globals; @@ -244,8 +246,10 @@ public class Response implements HttpSer */ private final List<Cookie> cookies = new ArrayList<>(); - // --------------------------------------------------------- Public Methods + private HttpServletResponse applicationResponse = this; + + // --------------------------------------------------------- Public Methods /** * Release all object references, and initialize instance variables, in @@ -262,6 +266,7 @@ public class Response implements HttpSer errorState.set(0); isCharacterEncodingSet = false; + applicationResponse = null; if (Globals.IS_SECURITY_ENABLED || Connector.RECYCLE_FACADES) { if (facade != null) { facade.clear(); @@ -364,6 +369,7 @@ public class Response implements HttpSer */ protected ResponseFacade facade = null; + /** * @return the <code>ServletResponse</code> for which this object * is the facade. @@ -372,7 +378,32 @@ public class Response implements HttpSer if (facade == null) { facade = new ResponseFacade(this); } - return (facade); + if (applicationResponse == null) { + applicationResponse = facade; + } + return applicationResponse; + } + + + /** + * Set a wrapped HttpServletResponse to pass to the application. Components + * wishing to wrap the response should obtain the response via + * {@link #getResponse()}, wrap it and then call this method with the + * wrapped response. + * + * @param applicationResponse The wrapped response to pass to the + * application + */ + public void setResponse(HttpServletResponse applicationResponse) { + // Check the wrapper wraps this request + ServletResponse r = applicationResponse; + while (r instanceof HttpServletResponseWrapper) { + r = ((HttpServletResponseWrapper) r).getResponse(); + } + if (r != facade) { + throw new IllegalArgumentException(sm.getString("response.illegalWrap")); + } + this.applicationResponse = applicationResponse; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org