dev@glassfish.java.net

Re: expires-header valve

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Thu, 17 Jan 2008 13:22:12 -0500

Salut,

w.rittmeyer wrote:
> Jeanfrancois Arcand wrote:
>>> Hi Jeanfrancois,
>>>
>>> I had a look at your blog posting but I nevertheless wonder how to
>>> pass values to the Valves setter methods.
>>>
>>> Well I guess you do /not/ want to change the domains.xml-DTD but /I/
>>> think s.th. along the lines of the following would be nice:
>>>
>>> <virtual-server hosts="${com.sun.aas.hostName}" ...>
>>> <property name="docroot" value="${com.sun.aas.instanceRoot}/docroot"/>
>>> <!-- ... more properties for virtual-server -->
>>> <valve name="someValve" classname="x.y.z.ExpiresHeaderValve">
>>> <property name="contentTypes" value="text/plain,text/css" />
>>> <property name="addOnYears" value="1" />
>>> <!-- ... more properties for valve -->
>>> </valve>
>>> </virtual-server>
>>>
>>> And of course for web-modules as well.
>>
>> Agree. Can you file an RFE here once you have a chance:
>>
>> https://glassfish.dev.java.net/servlets/ProjectIssues
>>
>
>
> Hi Jeanfrancois,
>
> I've done just that:
>
> https://glassfish.dev.java.net/issues/show_bug.cgi?id=4006

Thanks!

>
>>>
>>> And corresponding asadmin-commands like
>>>
>>> asadmin create-valve --class xyz --parent-type virtual-server
>>> --parent-id server --target server somevalve
>
> (...)
>
>>>
>>
>> Can you file another RFE? We can certainly evaluate that one for v3.
>>
>
> And for this one it is
>
> https://glassfish.dev.java.net/issues/show_bug.cgi?id=4007

Thanks!

>
>
>>
>>>
>>>>>
>>>>> Considering this I think using a Valve would be more fine-grained
>>>>> than the default-web.xml while still coarser than a filter for each
>>>>> web-app.
>>>>>
>>>>>
>>>>> But I will give it some more thoughts.
>>>>
>>>> Let us know which solution you picked :-)
>>>>
>>>
>>> I still would like to go down the Valve route but right now I think
>>> it might not be so good an idea with GF. Though of course I hope you
>>> can prove me wrong ;-)
>>
>> No Valve is a good solution for what you want. An alternative would
>> consist of extending Grizzly directly and inject your header at the
>> bytes level, before the response is sent. That alternative will
>> perform faster than a Valve. What exact information do you need to
>> have to decide when to inject the new header?
>>
>
> I would need to have access to the content-type header as it should be
> possible to limit this for certain types only (like "image/png" or
> "text/css"). Furthermore I would have to check whether the expires
> header is already set. In this case it would have to be left unchanged.
> And I'd like to be able to configure for which content-types the header
> shall be set and how many years shall be added to the current timestamp.
>
>
>> In Grizzly, you can inject your header by having your own
>> ProcessorTask (the class responsible for manipuating the
>> request/response).
>>
>
> Irrespective of the current task at hand I very much hope that the above
> changes/RFEs will be implemented for any future requirements.


Agree.

>
> I do not know enough about the Grizzly-Glassfish integration. How can I
> use my own ProcessorTask for Grizzly in GF? Would this be possible with
> v2_UR1 or with v3 only?

No works since v2. Mainly, you just have to do something like:

> 10 package your.package;
> 11
> 12 import com.sun.enterprise.web.connector.grizzly.SelectorThread;
> 13 import com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask;
> 14
> 15 public class ExpireHeaderSelectorThread extends SelectorThread {
> 16 /**
> 17 * Create <code>ProcessorTask</code> objects and configure it to be ready
> 18 * to proceed request.
> 19 */
> 20 @Override
> 21 protected ProcessorTask newProcessorTask(boolean initialize){
> 22 DefaultProcessorTask task =
> 23 new DefaultProcessorTask(initialize, bufferResponse){
> 24 /**
> 25 * When committing the response, we have to validate the set of headers, as
> 26 * well as setup the response filters.
> 27 */
> 28 @Override
> 29 protected void prepareResponse() {
> 30 super.prepareResponse();
> 31 // Add date header
> 32 if (!response.containsHeader("expire-headers")){
> 33 response.addHeader("expire-headers", "your expire header");
> 34 }
> 35 }
> 36 };
> 37 return configureProcessorTask(task);
> 38 }
> 39 }

To tell Grizzly to use your SelectorThread, just add the following
property under the http-listener:

<property name="selectorThreadImpl"
value="your.package.ExpireHeaderSelectorThread"/>

Now all requests to that listener will be executed by your Selector.

Hope that help.

-- Jeanfrancois




>
>
> Regards,
>
> Wolfram
>
>> A+
>>
>> -- Jeanfrancois
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>