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;
}