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

ServletResponce.addHeader("Set-Cookie","value") call in Portlet during rendering causes all  deletion of all other cookies

    Details

    • Fix Priority:
      3

      Description

      Adding cookie via setHeader call causes deletion of other cookies. Only last setted cookie will present on the client

      The code snippet is :

      public void addCookie(HttpServletRequest request,HttpServletResponse response, String name, String value, String path, String domain, String expiration, boolean isSecured) {
      response.addHeader("Set-Cookie", getCookieStringValue(name, value, path, domain, expiration, true, isSecured));

      After deep Liferay analysis I found, that headder adding is realised using this structure :

      /**

      • @author Alexander Chow
        */
        public class CacheResponseUtil {

      public static void setHeaders(
      HttpServletResponse response, Map<String, List<Header>> headers) {

      for (Map.Entry<String, List<Header>> entry : headers.entrySet()) {
      String headerKey = entry.getKey();
      List<Header> headerValues = ListUtil.copy(entry.getValue());

      for (Header header : headerValues) {
      int type = header.getType();

      if (type == Header.COOKIE_TYPE)

      { response.addCookie(header.getCookieValue()); }

      else if (type == Header.DATE_TYPE)

      { response.setDateHeader(headerKey, header.getDateValue()); }

      else if (type == Header.INTEGER_TYPE)

      { response.setIntHeader(headerKey, header.getIntValue()); }

      else if (type == Header.STRING_TYPE)

      { response.setHeader(headerKey, header.getStringValue()); }

      }
      }
      }

      As we see, for Header.COOKIE_TYPE the call is response.addCookie(header.getCookieValue());

      BUT for the Header.STRING_TYPE the call is
      response.setHeader(headerKey, header.getStringValue());

      This causes the code below in appServer

      public void setHeader(String name, String value) {
      char cc=name.charAt(0);
      if( cc=='C' || cc=='c' )

      { if( checkSpecialHeader(name, value) ) return; }

      headers.setValue(name).setString( value);
      }

      public MessageBytes setValue( String name ) {
      for ( int i = 0; i < count; i++ ) {
      if(headers[i].getName().equalsIgnoreCase(name)) {
      for ( int j=i+1; j < count; j++ ) {
      if(headers[j].getName().equalsIgnoreCase(name))

      { removeHeader(j--); }

      }
      return headers[i].getValue();
      }
      }
      MimeHeaderField mh = createHeader();
      mh.getName().setString(name);
      return mh.getValue();
      }

      As a result all headers with name Set-Cookie will be deleted, and only last one added.

      On my point of view the correct code should be like that :
      else if (type == Header.STRING_TYPE) {
      if(name.equals("Set-Cookie"))

      { response.addHeader(headerKey, header.getStringValue()); }

      else

      { response.setHeader(headerKey, header.getStringValue()); }

      }

        Attachments

          Activity

            People

            Assignee:
            support-lep@liferay.com SE Support
            Reporter:
            vasekaa Vasily Abakumov
            Participants of an Issue:
            Recent user:
            Esther Sanz
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Days since last comment:
              6 years, 13 weeks, 3 days ago

                Packages

                Version Package