users@jersey.java.net

Re: [Jersey] Bug in Jersey's header parser?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 22 Jul 2008 16:01:12 +0200

Hi Markus,

You have a typo:

   "If-Non-Match"

should be:

   "If-None-Match"

The java.util.Date constructor is deprecated and the JavaDoc says:

     Deprecated. As of JDK version 1.1, replaced by Calendar.set(year +
1900, month, date) or GregorianCalendar(year + 1900, month, date).

     Allocates a Date object and initializes it so that it represents
midnight, local time, at the beginning of the day specified by the year,
month, and date arguments.

     Parameters:
         year - the year minus 1900.
         month - the month between 0-11.
         date - the day of the month between 1-31.

Notice the "the year minus 1900".

I recommend you use GregorianCalendar.

Jersey will format date objects according to RFC 1123 (US locale) which
is the recommended format for HTTP dates. Annoyingly:

   new GregorianCalendar(2003, Calendar.FEBRUARY, 1).getTime()

returns a header of:

   Last-Modified Fri, 31 Jan 2003 23:00:00 GMT

i.e. one day behind what is declared. I think it is a rounding error
when formatting.

Paul.

Markus KARG wrote:
> 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
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109