RE: Re: Re: Last-Modified Header
Hi Rob, Actually, we did try to facilitate this use case in Restlet 2.0. We introduced the RepresentationInfo class, subclass of Variant and parent of Representation. It contains two properties, modificationDate and tag, necessary for conditional processing. In ServerResource, there are also getInfo() and getInfo(Variant) methods which return RepresentationInfo instances. By default, it calls get() and get(Variant) methods, so it is really an optional optimization. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org/ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com/ http://www.noelios.com De : Rob Heittman [mailto:rob.heitt...@solertium.com] Envoyé : mercredi 10 juin 2009 19:23 À : discuss@restlet.tigris.org Objet : Re: Re: Re: Last-Modified Header I can't imagine how the framework would be able to figure that out on its own without being able to examine the Representation ... chicken, egg, chicken, egg. Still, I understand the concern if Representations are expensive to generate. I wonder if the conditional logic fetches the entity body if the last modified date has not changed. If it doesn't (and it probably shouldn't) then you could just craft a Representation subclass in which the expensive stuff only happens when the entity body is actually read -- the headers should be enough to tell the engine how to handle the conditional GET. ** disclaimer ** I really don't know if that approach works, but I think it ought to. - Rob On Wed, Jun 10, 2009 at 1:11 PM, Sherif Ahmed sherifah...@hotmail.com wrote: Cool, This works as you indicate. However implementing this way has a downside. Would be nice that the framework could take care of sending a 304 even without having to get a concrete Representation which has a date set. The idea is to avoid creating a Representation if the Resource has not changed and Restlet could send a 304 directly thus avoiding the cost that may be associated with building a Representation. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447 http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361 007 dsMessageId=2361007 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361273
Re: Re: Re: Last-Modified Header
Excellent. I missed that one in the mix of ServerResource newness! I'll try it out on some expensive Representations and publish a benchmark. On Thu, Jun 11, 2009 at 9:23 AM, Jerome Louvel jerome.lou...@noelios.comwrote: Hi Rob, Actually, we did try to facilitate this use case in Restlet 2.0. We introduced the RepresentationInfo class, subclass of Variant and parent of Representation. It contains two properties, “modificationDate” and “tag”, necessary for conditional processing. In ServerResource, there are also getInfo() and getInfo(Variant) methods which return RepresentationInfo instances. By default, it calls get() and get(Variant) methods, so it is really an optional optimization. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com *De :* Rob Heittman [mailto:rob.heitt...@solertium.com] *Envoyé :* mercredi 10 juin 2009 19:23 *À :* discuss@restlet.tigris.org *Objet :* Re: Re: Re: Last-Modified Header I can't imagine how the framework would be able to figure that out on its own without being able to examine the Representation ... chicken, egg, chicken, egg. Still, I understand the concern if Representations are expensive to generate. I wonder if the conditional logic fetches the entity body if the last modified date has not changed. If it doesn't (and it probably shouldn't) then you could just craft a Representation subclass in which the expensive stuff only happens when the entity body is actually read -- the headers should be enough to tell the engine how to handle the conditional GET. ** disclaimer ** I really don't know if that approach works, but I think it ought to. - Rob On Wed, Jun 10, 2009 at 1:11 PM, Sherif Ahmed sherifah...@hotmail.com wrote: Cool, This works as you indicate. However implementing this way has a downside. Would be nice that the framework could take care of sending a 304 even without having to get a concrete Representation which has a date set. The idea is to avoid creating a Representation if the Resource has not changed and Restlet could send a 304 directly thus avoiding the cost that may be associated with building a Representation. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361007 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361296
RE: Re: Re: Last-Modified Header
Cool! This class definitely needs more tests and feed-back to be as perfect as possible when 2.0 RC1 goes out. Cheers, Jerome De : Rob Heittman [mailto:rob.heitt...@solertium.com] Envoyé : jeudi 11 juin 2009 16:06 À : discuss@restlet.tigris.org Objet : Re: Re: Re: Last-Modified Header Excellent. I missed that one in the mix of ServerResource newness! I'll try it out on some expensive Representations and publish a benchmark. On Thu, Jun 11, 2009 at 9:23 AM, Jerome Louvel jerome.lou...@noelios.com wrote: Hi Rob, Actually, we did try to facilitate this use case in Restlet 2.0. We introduced the RepresentationInfo class, subclass of Variant and parent of Representation. It contains two properties, modificationDate and tag, necessary for conditional processing. In ServerResource, there are also getInfo() and getInfo(Variant) methods which return RepresentationInfo instances. By default, it calls get() and get(Variant) methods, so it is really an optional optimization. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org/ http://www.restlet.org Noelios Technologies ~ Co-founder~ http://www.noelios.com/ http://www.noelios.com De: Rob Heittman [mailto:rob.heitt...@solertium.com] Envoy頺 mercredi 10 juin 2009 19:23 : discuss@restlet.tigris.org Objet: Re: Re: Re: Last-Modified Header I can't imagine how the framework would be able to figure that out on its own without being able to examine the Representation ... chicken, egg, chicken, egg. Still, I understand the concern if Representations are expensive to generate. I wonder if the conditional logic fetches the entity body if the last modified date has not changed. If it doesn't (and it probably shouldn't) then you could just craft a Representation subclass in which the expensive stuff only happens when the entity body is actually read -- the headers should be enough to tell the engine how to handle the conditional GET. ** disclaimer ** I really don't know if that approach works, but I think it ought to. - Rob On Wed, Jun 10, 2009 at 1:11 PM, Sherif Ahmed sherifah...@hotmail.com wrote: Cool, This works as you indicate. However implementing this way has a downside. Would be nice that the framework could take care of sending a 304 even without having to get a concrete Representation which has a date set. The idea is to avoid creating a Representation if the Resource has not changed and Restlet could send a 304 directly thus avoiding the cost that may be associated with building a Representation. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447 http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361007 dsMessageId=2361007 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361307
Re: Last-Modified Header
Hi Sherif, For custom headers whatever name you give, entity.modificationDate, will be used. However, what you probably meant to do is use setModificationDate(new Date()) on the entity/response representation. ie. representation.setModificationDate(new Date()); Jon Sherif Ahmed wrote: I've been trying to add Last-Modified Header via the following code in a Filter afterHandle method Form responseHeaders = (Form) response.getAttributes().get(org.restlet.http.headers); if (responseHeaders == null) { responseHeaders = new Form(); response.getAttributes().put(org.restlet.http.headers, responseHeaders); } responseHeaders.add(entity.modificationDate, Sun, 06 Nov 2005 14:59:42 GMT); However the header in the HTTP Response is not Last-Modified as I would have expected, rather a custom header entity.modificationDate: Sun, 06 Nov 2005 14:59:42 GMT Quick response would be much appreciated -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360858 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360893
RE: Re: Last-Modified Header
Thanks Jon. What I am trying to accomplish is implementing the Last-Modified / If-Modified-Since logic. Where I would tag responses with a uniform Last-Modified header for all resources/representations and when a request comes in with a If-Modified-Since header I'd send appropriate HTTP 304 response or completely process the response. Ideas/Best Practices to accomplish this without having to get the HttpServletRequest/Response objects to do this would be great Hi Sherif, For custom headers whatever name you give, entity.modificationDate, will be used. However, what you probably meant to do is use setModificationDate(new Date()) on the entity/response representation. ie. representation.setModificationDate(new Date()); Jon Sherif Ahmed wrote: I've been trying to add Last-Modified Header via the following code in a Filter afterHandle method Form responseHeaders = (Form) response.getAttributes().get(org.restlet.http.headers); if (responseHeaders == null) { responseHeaders = new Form(); response.getAttributes().put(org.restlet.http.headers, responseHeaders); } responseHeaders.add(entity.modificationDate, Sun, 06 Nov 2005 14:59:42 GMT); However the header in the HTTP Response is not Last-Modified as I would have expected, rather a custom header entity.modificationDate: Sun, 06 Nov 2005 14:59:42 GMT Quick response would be much appreciated -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360858 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360959
Re: Re: Last-Modified Header
Restlet provides the 304 plumbing for you. Just setModificationDate() on your Resource's returned Representation as Jon suggests. The GET headers returned from my Web site which calls this function are below. If you hit this resource with Firefox and watch it with Firebug as you refresh (which does conditional GETs), you'll see 304s being returned instead. This is all done by Restlet internally -- my code doesn't know anything about conditional processing. curl -I http://solertium.com/index.html HTTP/1.1 200 OK Expires: Wed, 10 Jun 2009 15:55:42 GMT Content-Type: text/html; charset=UTF-8 Last-Modified: Wed, 10 Jun 2009 15:40:42 GMT Content-Length: 11302 Date: Wed, 10 Jun 2009 15:40:42 GMT Set-Cookie: BROWSERID=cQv0DC1n-c0fgM3-Jl; Path=/; HttpOnly Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept Server: Noelios-Restlet-Engine/1.2.m1 On Wed, Jun 10, 2009 at 11:36 AM, Sherif Ahmed sherifah...@hotmail.comwrote: Thanks Jon. What I am trying to accomplish is implementing the Last-Modified / If-Modified-Since logic. Where I would tag responses with a uniform Last-Modified header for all resources/representations and when a request comes in with a If-Modified-Since header I'd send appropriate HTTP 304 response or completely process the response. Ideas/Best Practices to accomplish this without having to get the HttpServletRequest/Response objects to do this would be great Hi Sherif, For custom headers whatever name you give, entity.modificationDate, will be used. However, what you probably meant to do is use setModificationDate(new Date()) on the entity/response representation. ie. representation.setModificationDate(new Date()); Jon Sherif Ahmed wrote: I've been trying to add Last-Modified Header via the following code in a Filter afterHandle method Form responseHeaders = (Form) response.getAttributes().get(org.restlet.http.headers); if (responseHeaders == null) { responseHeaders = new Form(); response.getAttributes().put(org.restlet.http.headers, responseHeaders); } responseHeaders.add(entity.modificationDate, Sun, 06 Nov 2005 14:59:42 GMT); However the header in the HTTP Response is not Last-Modified as I would have expected, rather a custom header entity.modificationDate: Sun, 06 Nov 2005 14:59:42 GMT Quick response would be much appreciated -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360858 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360959 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360964
RE: Last-Modified Header
Brilliant.. The more I use Restlet the more I am liking it indeed. Now does Restlet has a framework to take care of Gzip encoding results when the Request headers indicate that the request is from a client that supports this encoding (all modern browsers do) I've been trying to add Last-Modified Header via the following code in a Filter afterHandle method Form responseHeaders = (Form) response.getAttributes().get(org.restlet.http.headers); if (responseHeaders == null) { responseHeaders = new Form(); response.getAttributes().put(org.restlet.http.headers, responseHeaders); } responseHeaders.add(entity.modificationDate, Sun, 06 Nov 2005 14:59:42 GMT); However the header in the HTTP Response is not Last-Modified as I would have expected, rather a custom header entity.modificationDate: Sun, 06 Nov 2005 14:59:42 GMT Quick response would be much appreciated -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2360997
RE: Re: Re: Last-Modified Header
Cool, This works as you indicate. However implementing this way has a downside. Would be nice that the framework could take care of sending a 304 even without having to get a concrete Representation which has a date set. The idea is to avoid creating a Representation if the Resource has not changed and Restlet could send a 304 directly thus avoiding the cost that may be associated with building a Representation. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361007
Re: Re: Re: Last-Modified Header
I can't imagine how the framework would be able to figure that out on its own without being able to examine the Representation ... chicken, egg, chicken, egg. Still, I understand the concern if Representations are expensive to generate. I wonder if the conditional logic fetches the entity body if the last modified date has not changed. If it doesn't (and it probably shouldn't) then you could just craft a Representation subclass in which the expensive stuff only happens when the entity body is actually read -- the headers should be enough to tell the engine how to handle the conditional GET. ** disclaimer ** I really don't know if that approach works, but I think it ought to. - Rob On Wed, Jun 10, 2009 at 1:11 PM, Sherif Ahmed sherifah...@hotmail.comwrote: Cool, This works as you indicate. However implementing this way has a downside. Would be nice that the framework could take care of sending a 304 even without having to get a concrete Representation which has a date set. The idea is to avoid creating a Representation if the Resource has not changed and Restlet could send a 304 directly thus avoiding the cost that may be associated with building a Representation. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361007 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2361011