Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-87054

Private render parameters cannot be retrieved from the underlying HttpSession until the user has signed-in

    Details

      Description

      Portlet 3.0 TCK Test Failures

      This problem manifests itself in the following Portlet 3.0 TCK test failures:

      • V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2
      • V2DispatcherTests_SPEC2_19_IncludeServletResource_dispatch2

      Problem Background

      This problem only occurs when Liferay Portal has first started and the user has not signed-in. Therefore, a portlet that manifests the problem (such as the aforementioned tests found in V2DispatcherTests.war) must have been either:

      1) Deployed during a previous run and added to a portal page prior to shutdown
      2) Deployed after startup, but automatically added to a portal page by an automated process

      Once a user has signed-in once, then the problem goes away – even if the user signs out.

      Technical Details

      When a user hasn't yet signed-in since the portal was started, the underlying HttpSession is an instance of org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionAdaptor.

      However, after a user has signed-in, the underlying HttpSession is an instance of org.apache.catalina.session.StandardSessionFacade.

      The problem manifests itself when a user hasn't yet signed in because HttpSessionAdaptor.getAttribute(String) prepends the session attribute name with a prefix. More details about the prefix are provided at the bottom of this section, just prior to the "Steps to Reproduce" section.

      The Portlet 3.0 TCK V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2 test initially renders on the page with a clickable hyperlink. When the link is clicked, it invokes the following RenderURL:

      http://localhost:8080/web/guest/forwardservletresource_dispatch2
      ?p_p_id=DispatcherTests_SPEC2_19_ForwardServletResource_WAR_tckV2DispatcherTests
      &p_p_lifecycle=0
      &p_p_state=normal
      &p_p_mode=view
      &_DispatcherTests_SPEC2_19_ForwardServletResource_WAR_tckV2DispatcherTests_qparm2=renderVal2
      

      As shown in the URL, the RenderURL has a private render parameter named qparm2 with value "renderVal2".

      Invoking the URL will cause the render(RenderRequest portletReq, RenderResponse portletResp) method to be called.

      At line#103, the following code creates a ResourceURL:

      ResourceURL resurl = portletResp.createResourceURL();
      

      The Javadoc for MimeResponse.createResourceURL() states:

      If allowed by the cacheability setting, public and private render parameters are added to the URL with their current values.

      Since the default cacheability is "cacheLevelPage", the qparam2 private render parameter should be added to the URL. The problem is that it's not being added, which causes V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2 to subsequently fail at line 143. The reason why it fails is because the value of qparm2 should have two values:

      The problem is that only "qvalue2" is found as a value.

      To understand why there is only one value, it is necessary to see how Liferay Portal stores public/private render parameters. When the RenderRequest is created, PortletRequestImpl.init(...) is called which executes the following code on line#757:

      RenderParametersPool.put(
      	request, plid, _portletName, privateRenderParameters);
      

      This successfully creates an underlying HttpSession attribute with the key "PORTLET_RENDER_PARAMETERS" due to line#146 of RenderParametesPool.java:

      session.setAttribute(
      	WebKeys.PORTLET_RENDER_PARAMETERS, renderParametersPool);
      

      Coming back to the original problem – the call to portletResp.createResourceURL() does not create a URL that contains the private render parameter "qvalue2" value. The reason why is because line#1602 of PortletURLImpl.java executes the following code:

      Map<String, String[]> renderParameters = RenderParametersPool.get(
      	_request, _plid, _portlet.getPortletId());
      

      And the value of renderParameters is null, rather than a map that contains a map entry with key "qparm2" with value "qvalue2".

      The reason why it is null is because the underlying HttpServletRequest is decorated by an instance of org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionAdaptor which attempts to add a prefix to the session attribute name, specifically it tries to get the value for an attribute with name "equinox.http.tck-V2DispatcherTestsPORTLET_RENDER_PARAMETERS_" instead of simply "PORTLET_RENDER_PARAMETERS_"

      Steps to Reproduce

      1. Deploy the attached tck-V2DispatcherTests.war artifact to $LIFERAY_HOME/deploy

      2. Add the portlet named "DispatcherTests_SPEC2_19_ForwardServletResource" to a portal page

      3. Reload the page

      4. Click on the " V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2" hyperlink

      Expected Results

      The portlet test results indicate "Success" for V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2

      Actual Results

      The portlet test results indicate "Failure" for V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Days since last comment:
                37 weeks, 3 days ago

                Packages

                Version Package