users@jersey.java.net

Bug in Jersey's header parser?

From: Markus KARG <markus.karg_at_gmx.net>
Date: Sat, 19 Jul 2008 20:37:59 +0200

To learn about HTTP caching and its benefit to RESTful WebServices I
wrote a small JAX-RS resource that prints out the If-Modified-Since,
If-Unmodified-Since, If-Match and If-Non-Match headers included possibly
in GET requests sent by IE6 and Firefox3. I was somewhat shocked by the
result: None of the browsers seems to care for ETag (I included one in
the initial response but revalidation request didn't include
If-Non-Match to make a hard validation), but both browsers included a
totally strange date in If-Modified-Since. My initial request included a
max-age of 5 seconds, and a last modification date of 2003-01-01. So for
five seconds the browser's cache is fresh and no revalidation will
occure (works well in both browsers). But after the five seconds, I
expect to find a "If-Modified-Since" with the date of 2003-01-01 to be
included in the revalidation request.

But the If-Modified-Since was: "If-Modified-Since: Sat, 31 Jan 3903
23:00:00 GMT"!

3903-01-31???

I modified the last modification date in my resource to be a different
one, and as a result I got a changed If-Modified-Since -- but still in
the year 39xx. Since the behaviour happens in both, IE and Firefix, I am
assuming that there is a bug in Jersey, either in the header parser, or
in the response builder.

Here is my source code. Maybe I used the response builder in a wrong way?

@GET
@Path("{id}.txt")
@ProduceMime("text/plain")
public Response processSampleGetArticleRequest(
@Context final UriInfo uriInfo,
@HeaderParam("Cache-Control") final String cacheControl,
@HeaderParam("Keep-Alive") final String keepAlive,
@HeaderParam("If-Match") final String ifMatch,
@HeaderParam("If-Non-Match") final String ifNonMatch,
@HeaderParam("If-Modified-Since") final String ifModifiedSince,
@HeaderParam("If-Unmodified-Since") final String ifUnmodifiedSince) {
  final String s = Long.toString(System.currentTimeMillis());
  System.out.println(String.format("GET (Cache-Control: %s, Keep-Alive:
%s, If-Match: %s, If-Non-Match: %s, If-Modified-Since: %s,
If-Unmodified-Since: %s) %s : %s",
   cacheControl, keepAlive, ifMatch, ifNonMatch, ifModifiedSince,
ifUnmodifiedSince, uriInfo.getPath(), s));
  final CacheControl cacheControl2 = new CacheControl();
  cacheControl2.setMaxAge(5);
  return Response.ok(s).lastModified(new Date(2003, 01, 01)).tag(new
EntityTag("11111", false)).cacheControl(cacheControl2).build();
}

Here is what the browsers asked for:

GET (Cache-Control: null, Keep-Alive: null, If-Match: null,
If-Non-Match: null, If-Modified-Since: Sat, 31 Jan 3903 23:00:00 GMT,
If-Unmodified-Since: null) x/x.txt : 1216492585578

Any ideas?

Thanks!
Markus

-- 
http://www.xing.com/go/invita/58469