Author: fmeschbe
Date: Wed Mar 24 07:06:53 2010
New Revision: 926955

URL: http://svn.apache.org/viewvc?rev=926955&view=rev
Log:
SLING-1456 Ensure proper setting of request attributes indicating request 
inclusion
  - Add Servlet API attribute names as constants
  - Add setting/resetting in the SlingRequestDispatcher
  - Add new attribute to provided the RequestPathInfo of the includer

Modified:
    
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/SlingConstants.java
    
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
    
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java

Modified: 
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/SlingConstants.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/SlingConstants.java?rev=926955&r1=926954&r2=926955&view=diff
==============================================================================
--- 
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/SlingConstants.java 
(original)
+++ 
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/SlingConstants.java 
Wed Mar 24 07:06:53 2010
@@ -53,9 +53,9 @@ public class SlingConstants {
     /**
      * The name of the request attribute containing the <code>Servlet</code>
      * which included the servlet currently being active (value is
-     * "org.apache.sling.api.include.servlet"). This attribute is
-     * <code>null</code> if the current servlet is the servlet handling the
-     * client request.
+     * "org.apache.sling.api.include.servlet"). This attribute is only set if
+     * the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
      * <p>
      * The type of the attribute value is <code>javax.servlet.Servlet</code>.
      */
@@ -63,17 +63,128 @@ public class SlingConstants {
 
     /**
      * The name of the request attribute containing the <code>Resource</code>
-     * underlying the <code>Servlet</code> which included the servlet
-     * currently being active (value is
-     * "org.apache.sling.api.include.resource"). This attribute is
-     * <code>null</code> if the current servlet is the servlet handling the
-     * client request.
+     * underlying the <code>Servlet</code> which included the servlet currently
+     * being active (value is "org.apache.sling.api.include.resource"). This
+     * attribute is only set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
      * <p>
      * The type of the attribute value is
      * <code>org.apache.sling.api.resource.Resource</code>.
      */
     public static final String ATTR_REQUEST_CONTENT = 
"org.apache.sling.api.include.resource";
 
+    /**
+     * The name of the request attribute containing the
+     * <code>RequestPathInfo</code> underlying the <code>Servlet</code> which
+     * included the servlet currently being active (value is
+     * "org.apache.sling.api.include.request_path_info"). This attribute is 
only
+     * set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is
+     * <code>org.apache.sling.api.request.RequestPathInfo</code>.
+     */
+    public static final String ATTR_REQUEST_PATH_INFO = 
"org.apache.sling.api.include.request_path_info";
+
+    /**
+     * The name of the request attribute containing the
+     * <code>HttpServletRequest.getRequestURI()</code> of the request which
+     * included the servlet currently being active underlying the
+     * <code>Servlet</code> which included the servlet currently being active
+     * (value is "javax.servlet.include.request_uri"). This attribute is only
+     * set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is <code>String</code>.
+     * <p>
+     * <b>Note:</b> In Sling, the
+     * <code>HttpServletRequest.getRequestURI()</code> method will always 
return
+     * the same result regardless of whether it is called from the client
+     * request processing servlet or script or from an included servlet or
+     * script. This request attribute is set for compatibility with the Servlet
+     * API specification.
+     */
+    public static final String ATTR_INCLUDE_REQUEST_URI = 
"javax.servlet.include.request_uri";
+
+    /**
+     * The name of the request attribute containing the
+     * <code>HttpServletRequest.getContextPath()</code> of the request which
+     * included the servlet currently being active underlying the
+     * <code>Servlet</code> which included the servlet currently being active
+     * (value is "javax.servlet.include.context_path"). This attribute is only
+     * set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is <code>String</code>.
+     * <p>
+     * <b>Note:</b> In Sling, the
+     * <code>HttpServletRequest.getContextPath()</code> method will always
+     * return the same result regardless of whether it is called from the 
client
+     * request processing servlet or script or from an included servlet or
+     * script. This request attribute is set for compatibility with the Servlet
+     * API specification.
+     */
+    public static final String ATTR_INCLUDE_CONTEXT_PATH = 
"javax.servlet.include.context_path";
+
+    /**
+     * The name of the request attribute containing the
+     * <code>HttpServletRequest.getServletPath()</code> of the request which
+     * included the servlet currently being active underlying the
+     * <code>Servlet</code> which included the servlet currently being active
+     * (value is "javax.servlet.include.servlet_path"). This attribute is only
+     * set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is <code>String</code>.
+     * <p>
+     * <b>Note:</b> In Sling, the
+     * <code>HttpServletRequest.getServletPath()</code> method will always
+     * return the same result regardless of whether it is called from the 
client
+     * request processing servlet or script or from an included servlet or
+     * script. This request attribute is set for compatibility with the Servlet
+     * API specification.
+     */
+    public static final String ATTR_INCLUDE_SERVLET_PATH = 
"javax.servlet.include.servlet_path";
+
+    /**
+     * The name of the request attribute containing the
+     * <code>HttpServletRequest.getPathInfo()</code> of the request which
+     * included the servlet currently being active underlying the
+     * <code>Servlet</code> which included the servlet currently being active
+     * (value is "javax.servlet.include.path_info"). This attribute is only set
+     * if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is <code>String</code>.
+     * <p>
+     * <b>Note:</b> In Sling, the <code>HttpServletRequest.getPathInfo()</code>
+     * method will always return the same result regardless of whether it is
+     * called from the client request processing servlet or script or from an
+     * included servlet or script. This request attribute is set for
+     * compatibility with the Servlet API specification.
+     */
+    public static final String ATTR_INCLUDE_PATH_INFO = 
"javax.servlet.include.path_info";
+
+    /**
+     * The name of the request attribute containing the
+     * <code>HttpServletRequest.getQueryString()</code> of the request which
+     * included the servlet currently being active underlying the
+     * <code>Servlet</code> which included the servlet currently being active
+     * (value is "javax.servlet.include.query_string"). This attribute is only
+     * set if the serlvet or script is included via
+     * <code>RequestDispatcher.include</code> from another servlet or script.
+     * <p>
+     * The type of the attribute value is <code>String</code>.
+     * <p>
+     * <b>Note:</b> In Sling, the
+     * <code>HttpServletRequest.getQueryString()</code> method will always
+     * return the same result regardless of whether it is called from the 
client
+     * request processing servlet or script or from an included servlet or
+     * script. This request attribute is set for compatibility with the Servlet
+     * API specification.
+     */
+    public static final String ATTR_INCLUDE_QUERY_STRING = 
"javax.servlet.include.query_string";
+
     // ---------- Error handling 
-----------------------------------------------
 
     /**

Modified: 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java?rev=926955&r1=926954&r2=926955&view=diff
==============================================================================
--- 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
 (original)
+++ 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
 Wed Mar 24 07:06:53 2010
@@ -18,8 +18,6 @@
  */
 package org.apache.sling.engine.impl.request;
 
-import static org.apache.sling.api.SlingConstants.ATTR_REQUEST_CONTENT;
-import static org.apache.sling.api.SlingConstants.ATTR_REQUEST_SERVLET;
 import static 
org.apache.sling.engine.EngineConstants.SLING_CURRENT_SERVLET_NAME;
 
 import java.io.BufferedReader;
@@ -109,7 +107,7 @@ public class RequestData implements Buff
      * not be too small to prevent request aborts.
      */
     private static int maxCallCounter = DEFAULT_MAX_CALL_COUNTER;
-    
+
     /** The SlingMainServlet used for request dispatching and other stuff */
     private final SlingMainServlet slingMainServlet;
 
@@ -146,7 +144,7 @@ public class RequestData implements Buff
 
     /**
      * The name of the currently active serlvet.
-     * 
+     *
      * @see #setActiveServletName(String)
      * @see #getActiveServletName()
      */
@@ -508,7 +506,7 @@ public class RequestData implements Buff
             if (requestData.servletCallCounter >= maxCallCounter) {
                 throw new TooManyCallsException(name);
             }
-            
+
             // replace the current servlet name in the request
             Object oldValue = request.getAttribute(SLING_CURRENT_SERVLET_NAME);
             request.setAttribute(SLING_CURRENT_SERVLET_NAME, name);
@@ -549,12 +547,6 @@ public class RequestData implements Buff
                     requestPathInfo.getResourcePath());
             }
 
-            // set the request attributes of the include content data
-            servletRequest.setAttribute(ATTR_REQUEST_CONTENT,
-                currentContentData.getResource());
-            servletRequest.setAttribute(ATTR_REQUEST_SERVLET,
-                currentContentData.getServlet());
-
             contentDataStack.add(currentContentData);
             parent = currentContentData;
         } else {
@@ -575,23 +567,6 @@ public class RequestData implements Buff
             // remove the topmost content data object
             currentContentData = contentDataStack.removeLast();
 
-            if (contentDataStack.isEmpty()) {
-
-                // remove the request attributes if the stack is empty now
-                
servletRequest.removeAttribute(SlingConstants.ATTR_REQUEST_CONTENT);
-                
servletRequest.removeAttribute(SlingConstants.ATTR_REQUEST_SERVLET);
-
-            } else {
-
-                // otherwise reset the attributes of the including content data
-                ContentData including = contentDataStack.getLast();
-                servletRequest.setAttribute(ATTR_REQUEST_CONTENT,
-                    including.getResource());
-                servletRequest.setAttribute(ATTR_REQUEST_SERVLET,
-                    including.getServlet());
-
-            }
-
         } else {
             currentContentData = null;
         }
@@ -649,7 +624,7 @@ public class RequestData implements Buff
     public AdapterManager getAdapterManager() {
         return slingMainServlet.getAdapterManager();
     }
-    
+
     // ---------- BufferProvider -----------------------------------------
 
     public BufferProvider getBufferProvider() {

Modified: 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java?rev=926955&r1=926954&r2=926955&view=diff
==============================================================================
--- 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java
 (original)
+++ 
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java
 Wed Mar 24 07:06:53 2010
@@ -24,8 +24,9 @@ import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
+import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.request.RequestDispatcherOptions;
 import org.apache.sling.api.resource.Resource;
@@ -62,7 +63,39 @@ public class SlingRequestDispatcher impl
     public void include(ServletRequest request, ServletResponse sResponse)
             throws ServletException, IOException {
 
-        // TODO: set the javax.servlet.include.* attributes
+        // guard access to the request and content data: If the request is
+        // not (wrapping) a SlingHttpServletRequest, accessing the request Data
+        // throws an IllegalArgumentException and we cannot continue
+        final ContentData cd;
+        try {
+            cd = RequestData.getRequestData(request).getContentData();
+        } catch (IllegalArgumentException iae) {
+            throw new ServletException(iae.getMessage());
+        }
+
+        // ClassCastException is not expected here because we operate in
+        // HTTP requests only (it cannot be excluded though if some client
+        // code uses a ServletRequestWrapper rather than an
+        // HttpServletRequestWrapper ...)
+        final HttpServletRequest hRequest = (HttpServletRequest) request;
+
+        // set the inclusion request attributes from the current request
+        final Object v1 = setAttribute(request,
+            SlingConstants.ATTR_REQUEST_CONTENT, cd.getResource());
+        final Object v2 = setAttribute(request,
+            SlingConstants.ATTR_REQUEST_SERVLET, cd.getServlet());
+        final Object v3 = setAttribute(request,
+            SlingConstants.ATTR_REQUEST_PATH_INFO, cd.getRequestPathInfo());
+        final Object v4 = setAttribute(request,
+            SlingConstants.ATTR_INCLUDE_CONTEXT_PATH, 
hRequest.getContextPath());
+        final Object v5 = setAttribute(request,
+            SlingConstants.ATTR_INCLUDE_PATH_INFO, hRequest.getPathInfo());
+        final Object v6 = setAttribute(request,
+            SlingConstants.ATTR_INCLUDE_QUERY_STRING, 
hRequest.getQueryString());
+        final Object v7 = setAttribute(request,
+            SlingConstants.ATTR_INCLUDE_REQUEST_URI, hRequest.getRequestURI());
+        final Object v8 = setAttribute(request,
+            SlingConstants.ATTR_INCLUDE_SERVLET_PATH, 
hRequest.getServletPath());
 
         try {
 
@@ -70,10 +103,17 @@ public class SlingRequestDispatcher impl
 
         } finally {
 
-            // TODO: reset the javax.servlet.include.* attributes
+            // reset inclusion request attributes to previous values
+            request.setAttribute(SlingConstants.ATTR_REQUEST_CONTENT, v1);
+            request.setAttribute(SlingConstants.ATTR_REQUEST_SERVLET, v2);
+            request.setAttribute(SlingConstants.ATTR_REQUEST_PATH_INFO, v3);
+            request.setAttribute(SlingConstants.ATTR_INCLUDE_CONTEXT_PATH, v4);
+            request.setAttribute(SlingConstants.ATTR_INCLUDE_PATH_INFO, v5);
+            request.setAttribute(SlingConstants.ATTR_INCLUDE_QUERY_STRING, v6);
+            request.setAttribute(SlingConstants.ATTR_INCLUDE_REQUEST_URI, v7);
+            request.setAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH, v8);
 
         }
-
     }
 
     public void forward(ServletRequest request, ServletResponse response)
@@ -89,6 +129,16 @@ public class SlingRequestDispatcher impl
         // we already tested for this condition
         response.reset();
 
+        // ensure inclusion information attributes are not set
+        request.removeAttribute(SlingConstants.ATTR_REQUEST_CONTENT);
+        request.removeAttribute(SlingConstants.ATTR_REQUEST_SERVLET);
+        request.removeAttribute(SlingConstants.ATTR_REQUEST_PATH_INFO);
+        request.removeAttribute(SlingConstants.ATTR_INCLUDE_CONTEXT_PATH);
+        request.removeAttribute(SlingConstants.ATTR_INCLUDE_PATH_INFO);
+        request.removeAttribute(SlingConstants.ATTR_INCLUDE_QUERY_STRING);
+        request.removeAttribute(SlingConstants.ATTR_INCLUDE_REQUEST_URI);
+        request.removeAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH);
+
         // now just include as normal
         dispatch(request, response);
 
@@ -115,8 +165,8 @@ public class SlingRequestDispatcher impl
         return uri + '/' + path;
     }
 
-    private void dispatch(ServletRequest request,
-            ServletResponse sResponse) throws ServletException, IOException {
+    private void dispatch(ServletRequest request, ServletResponse sResponse)
+            throws ServletException, IOException {
 
         /**
          * TODO: I have made some quick fixes in this method for SLING-221 and
@@ -176,6 +226,13 @@ public class SlingRequestDispatcher impl
             info);
     }
 
+    private Object setAttribute(final ServletRequest request,
+            final String name, final Object value) {
+        final Object oldValue = request.getAttribute(name);
+        request.setAttribute(name, value);
+        return oldValue;
+    }
+
     private static class TypeOverwritingResourceWrapper extends 
ResourceWrapper {
 
         /** marker value for the resourceSupertType before trying to evaluate 
*/
@@ -203,8 +260,8 @@ public class SlingRequestDispatcher impl
         @Override
         public String getResourceSuperType() {
             if (resourceSuperType == UNSET_RESOURCE_SUPER_TYPE) {
-                resourceSuperType = 
ResourceUtil.getResourceSuperType(this.getResourceResolver(),
-                        this.resourceType);
+                resourceSuperType = ResourceUtil.getResourceSuperType(
+                    this.getResourceResolver(), this.resourceType);
             }
             return resourceSuperType;
         }


Reply via email to