Hello All,

I have a problem with my application of HTTPClient relating to the way that
HttpMethodBase::ParseResponseHeaders handles rejecting cookies.

My problem is that when one cookie in the set-cookie(2) header is considered
invalid (call to parser.validate throws an exception) (because the domain is
for a third party, for example) all cookies in the header that haven't been
process are dropped.  In my application, I want to reject cookies that don't
match the domain and accept cookies that do match the domain.  This problem
can not be solved with a new cookie policy because the problem is in how
HttpMethodBase::ParseResponseHeaders handles the exception thrown by
parser.validate.

RFC 2965 seems to suggest that accepting some cookies in the Set-Cookie2
header and rejecting others is ok.  See section 3.3.2: "To prevent possible
security or privacy violations, a user agent rejects A COOKIE according to
rules below." (emphasis is mine)

In addition, IE and Netscape do accept all of the valid cookies on a
Set-Cookie(2) header.  What is a valid cookie to IE and Netscape depends on
how you set the cookie policy within that program and is more complicated
that what HttpClient currently supports.

If this is a desired change, I have attached my implementation of
HttpMethodBase::ParseResponseHeaders to be added to HttpClient.  If
requested, I can also provide a patch.

Sincerely,
James.

protected void processResponseHeaders(HttpState state,
    HttpConnection conn) {
    LOG.trace("enter HttpMethodBase.processResponseHeaders(HttpState, "
        + "HttpConnection)");

    // add cookies, if any
    // should we set cookies?
    String cookieHeaderName = "set-cookie2";
    Header setCookieHeader = getResponseHeader(cookieHeaderName);
    if (null == setCookieHeader) { //ignore old-style if new is supported
        cookieHeaderName = "set-cookie";
        setCookieHeader = getResponseHeader(cookieHeaderName);
    }

    if (setCookieHeader != null) {

      // Parse cookies -- an error parsing the set-cookie header dumps all
      // cookies in this header.

      CookieSpec parser =
CookiePolicy.getSpecByPolicy(state.getCookiePolicy());
      Cookie[] cookies = null;
      try {
        cookies = parser.parse(
            conn.getHost(),
            conn.getPort(),
            getPath(),
            conn.isSecure(),
            setCookieHeader);
      }
      catch (MalformedCookieException e) {
        if (LOG.isWarnEnabled()) {
          LOG.warn("Could not parse " + cookieHeaderName + " header: \""
                   + setCookieHeader.getValue()
                   + "\". " + e.getMessage());
        }
      }

      // Validate cookies -- only valid cookies are added.  Invalid cookies
      // are logged and ignored.

      if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
          Cookie cookie = cookies[i];
          boolean accepted = true;
          try {
            parser.validate(
                conn.getHost(),
                conn.getPort(),
                getPath(),
                conn.isSecure(),
                cookie);
          }
          catch (MalformedCookieException e) {
            accepted = false;
            if (LOG.isWarnEnabled()) {
              LOG.warn("Cookie rejected: \""
                       + parser.formatCookie(cookie)
                       + "\". " + e.getMessage());
            }
          }
          if (accepted) {
            if (LOG.isDebugEnabled()) {
              LOG.debug("Cookie accepted: \""
                        + parser.formatCookie(cookie) + "\"");
            }
            state.addCookie(cookie);
          }
        }
      }
    }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to