users@jersey.java.net

Re: [Jersey] Re: java.io.File and conditional GETs

From: Rob Koberg <rob_at_koberg.com>
Date: Wed, 7 Apr 2010 15:33:41 -0700

Thanks Marc,

This seems to be working for me now. I have pasted the entire method below, but

Would you use the webdav implementation for jax-rs at:
https://webdav.dev.java.net/webdav-jaxrs

is there a different one? Something else?

Basically, I want to open up a directory on my server (but nothing
outside of that dir). Usually I will need to process the files PUT on
the server. Below is the full method so far. Note the remainingPath
path param, I suppose that could be a problem if an authenticated user
sends me a huge request path. Is there a better way to accept a
wildcard path?


  @GET
  @Path("{projectName}/lsb/{remainingPath: .+}")
  @Produces(MediaType.APPLICATION_XML)
  public Response getFile(
      @Context Request req,
      @Context HttpServletRequest httpreq,
      @PathParam("projectName") String projectName,
      @PathParam("remainingPath") String remainingPath
      ) {
    LOG.debug("projectName: {}", projectName);
    LOG.debug("remainingPath: {}", remainingPath);

    Project project = projectMgr.getProject(projectName);
    LOG.debug("project: {}", project);
    LOG.debug("project.getDir(): {}", project.getDir());

    File file = new File(project.getDir(), "lsb/" + remainingPath);
    LOG.debug("file: {}", file);

    if (!file.exists()) {
      return Response.status(Response.Status.NOT_FOUND).build();
    }
    if (!file.getAbsolutePath().startsWith(ProjectManager.getProjectsDir().getAbsolutePath()))
{
      return Response.status(Response.Status.FORBIDDEN).build();
    }

    DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    Date lastMod = new Date(file.lastModified());

    String reqLastMod = httpreq.getHeader("If-Modified-Since");
    Response.ResponseBuilder rrb = null;
    if (reqLastMod != null) {
      rrb = req.evaluatePreconditions(lastMod, new
EntityTag(dateFormat.format(lastMod)));;
    }
    if (rrb == null) {
      return Response.ok(file)
        .tag(dateFormat.format(lastMod))
        .lastModified(lastMod)
        .build();
    }
    return Response.notModified().build();
  }


On Wed, Apr 7, 2010 at 3:00 PM, Marc Hadley <marc.hadley_at_oracle.com> wrote:
> On Apr 7, 2010, at 4:59 PM, Rob Koberg wrote:
>
>> How about something like:
>>
>>
>>    String reqLastMod = httpreq.getHeader("If-Modified-Since");
>>    if (reqLastMod != null) {
>>      return req.evaluatePreconditions(Date.valueOf(reqLastMod),
>>             new EntityTag(httpreq.getHeader("If-None-Match"))).build();
>>    }
>>    return Response.ok(file).contentLocation(file.toURI()).build();
>>
>> ? Or is there a recommended way?
>>
> You aren't really checking the preconditions above, you are just comparing the value of the If-Modified-Since header with itself. What you need to do is get the last modified date from the backing file and use that in the call to req.evaluatePreconditions. That will see if there's an If-Modified-Since or whatever in the request and compare it to the value you passed in. A null return means the preconditions were met and you should go ahead and process the request, a non-null return means the pre-conditions weren't met and you should return the returned response after adding any additional metadata and building it.
>
> Marc.
>
>>
>> On Wed, Apr 7, 2010 at 1:34 PM, Rob Koberg <rob_at_koberg.com> wrote:
>>> Hi,
>>>
>>> What is the best way to handle conditional GETs when targeting files
>>> that exist on the local file system that are being retrieved through a
>>> jersey resource? Currently it looks like I am using
>>> com.sun.jersey.core.impl.provider.entity.FileProvider (which doesn't
>>> appear the javadoc, checking out the project now...). Perhaps that
>>> could/should place an ETag and Last-Modified header by default?
>>>
>>> thanks,
>>> -Rob
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>