I've added a property called "org.apache.cxf.http.cookie.separator" which one can set as a jaxrs:property, default is a colon but I've seen on Google the legacy clients can use a semicolon for separating simple cookie values (those containing name/value only). And indeed, HttpServletResponse implementation you're using is apparently using a combination of ";" and CRLF when Set-Cookie has been called a number of times which results in the same combination being used to separate multiple Cookie values...

If "org.apache.cxf.http.cookie.separator" is set to "crlf" then HttpHeadersImpl will use "\r\n" to split the values, but it can also be set to any other value you need, and it does not have to be of type String...

cheers, Sergey


Only one value:

[email protected]
|1295450533|d91I1lzvMwON0RHsSCCMLA==|tzeO3oQSbDxU3Qr86v9sIigVNy3mhx
wlBNPt3bqEr3g=; user_logged_in=true


I'll try the other changes later.


thanks,
V.

On Mon, Jan 18, 2010 at 3:58 PM, Sergey Beryozkin <[email protected]>wrote:

Hi


 We use something like this:

response.addHeader("Set-Cookie",
"[email protected]
|1295442881|laFf9MAZUTc7rvJqhq54rQ==|CX7PgJK0P4zEywRtG9ix+L98jTfILumYrPKYZ4luxfc=;
path=/; httpOnly");

called different times with different names (and also a secure only
cookie)
since we also need the httpOnly flag to be set thus it's not possible to
use
the normal javax. sevlet.http.Cookie class.


But this is a Set-Cookie header, not a Cookie header ? by the way, there is
a JAX-RS NewCookie utility class that might be used instead...Actually, I
see, you're probably using HttpServletResponse directly...



Tampering the request we see that the header value is :
[email protected]
|1295442881|laFf9MAZUTc7rvJqhq54rQ==|CX7PgJK0P4zEywRtG9ix+L98jTfILumYrPKYZ4luxfc=;
path=/; httpOnly
user_logged_in=true; path=/
[email protected]
|1263863681|+jZzblDmjCo1wWFZOdxRaQ==|3r1WMPuUk2ghrvl+3RmcIPLjueD8fjBYPnbBN/s+3j0=;
path=/; httpOnly; Secure

where the carriage return seems to be used aas separator.


AFAIK it is something (the carriage return) that is kind of an
internal/on-the-wire detail only and it is used for the readability
purposes, when the header value is too long. According to [2], the older
state management rfc, "the Set-Cookie response header comprises the token
Set-Cookie:, followed by a *comma-separated* list of one or more cookies."



To get the values I used this code:

I see...After your server replies with Set-Cookie, the code below is used
to retrieve the original cookies sent back by a client...


             String cookieHeaderString =
                  new org.apache.cxf.jaxrs.impl.MetadataMap<String,
String>(
                          (Map<String, List<String>>) m
                                  .get(Message.PROTOCOL_HEADERS))
                          .getFirst("Cookie");
          // XXX: In some systems instead of Cookie, cookie must be used.
          if (cookieHeaderString == null) {
              cookieHeaderString =
                      new org.apache.cxf.jaxrs.impl.MetadataMap<String,
String>(
                              (Map<String, List<String>>) m
                                      .get(Message.PROTOCOL_HEADERS))
                              .getFirst("cookie");
          }

the double call is because in linux+jboss+firefox instead of 'Cookie',
'cookie' is used.


Note that HttpHeaders is using a case-insensitive MetadataMap as required
by JAX-RS, you can do the same by doing new
org.apache.cxf.jaxrs.impl.MetadataMap(map, true, true);



changing the ; to ' when settinh the header value doesn't change the
behaviour.


I meant that the Cookie header string should contain a ',' as a separator
between multiple values. Given that HttpServletResponse does not add a ','
between different Set-Cookie values when you do multiple SetCookie on it, no
',' is present in the client request either. Can you confirm once again
please no ',' is available in a Cookie value ? [1] also says :


 the call to:
Map<String, Cookie> cookies = headers.getCookies();
alwasy returns only a cookie (the user_logged_in one).


Can you please do the following :

for (String value : message.get(Message.PROTOCOL_HEADERS).get("Cookie")) {

System.out.println(value);

}

will you get a single value containing something like

"[email protected]
|1295428834|7mMx6SxeIeSaWhygsOsAyA==|Iy/1xl/kOwderfdsdhAg/ip1Qsb0dwerQOJ8zDYJ34=;
user_logged_in=true"

or two values, one is


"[email protected]
|1295428834|7mMx6SxeIeSaWhygsOsAyA==|Iy/1xl/kOwderfdsdhAg/ip1Qsb0dwerQOJ8zDYJ34=;"

and the other one is :

"user_logged_in=true"

?

That is, I'd like to check if the underlying container sees the Cookie
headers containing a single value or two values.

perhaps, rather than doing multiple response.addHeader("SetCookie", value),
you can instead build a SetCookie string containing of multiple values
separated by ',' and then do response.addHeader("SetCookie", value) just
once ?

The problem is that I do not see neither in Http 1.1 [2] or [1] that a
'next line' can be used as a separator between multiple Cookie values.
Perhaps the multi-line string should be just folded back, due to the fact a
CRLF or LWS [2] have been used to separate multiple words ?

I guess what I can try to do is to let users to explcitly configure a
jaxrs:server endpoint with a property like
"org.apache.cxf.http.cookie.separator=crlf" ? First though, let me know if
you can update the server code as suggested above, for ',' being used as a
separator

thanks, Sergey




Cheers,
V.


[1] http://tools.ietf.org/html/rfc2109
[2] http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2



Reply via email to