History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: CACHE-120
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Lars Torunski
Reporter: Sander de Boer
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
OSCache

New nocache option when body contains a jsessionid

Created: 01/Nov/04 05:29 AM   Updated: 06/Nov/05 11:19 AM
Component/s: Filters
Affects Version/s: 2.1.1
Fix Version/s: 2.2 RC


 Description  « Hide
It would be usefull to add a nocache option that exclude requests containing jsessionid's(in body and/or url) to put them in the cache.

 All   Comments   Change History      Sort Order:
Andres March - [12/Mar/05 01:42 AM ]
Please be more specific

Andres March - [06/Apr/05 06:09 PM ]
I didn't post the Jira issue but this is what I think it means:

Provide the possibility to always regenerate the content (ignore the cache) if the session supplied with the request is tracked via URL (jsessionid exists the URL).

Then I could safely include <%=response.encodeUrl()%> links in my cached content. It is safe for both cookie- and url-rewriting sessions. The downside of course is that the content is not served from cache in the latter case. But still way better than a security nightmare.

I found some (ugly) workaround, which does more or less the same:
<cache:cache key="<%="index_lat" + request.isRequestedSessionIdFromURL()%>" time="30" scope="application" refresh="<%=request.isRequestedSessionIdFromURL()%>">

It reads like this: There are different cache keys for cookie and url-sessions. If it's url-session, the refresh attribute forces to regenerate the content.

Andres March - [06/Apr/05 06:10 PM ]
Let's discuss if this can be done efficiently

Lars Torunski - [06/Apr/05 11:46 PM ]
Introducing a "isCacheable" method (see CACHE-141):

/**
     * isCacheable is a method allowing subclass to decide if a response id
     * cachable or not.
     *
     * @param request The HTTP servlet request
     * @param response The HTTP servlet response
     * @return Returns a boolean indicating if the request can be cached or not.
     */
    protected boolean isCacheable(HttpServletRequest request, HttpServletResponse response) {
        boolean cachable = ! response.containsHeader("Cache-control");

if (log.isDebugEnabled()) {
            log.debug("<cache>: the response " + ((cachable) ? "is" : "is not") + " cachable.");
        }
        
return cachable;
    }


and change the SC_OK check to


                if ((cacheResponse.getStatus() == HttpServletResponse.SC_OK) && isCacheable(httpRequest, cacheResponse)) {


should allow to implement this.

Sander de Boer - [07/Apr/05 01:34 AM ]
yeah thats what I mean!

Lars Torunski - [08/Apr/05 12:29 AM ]
Should we split the method into

protected boolean isCacheable(HttpServletRequest request)
protected boolean isCacheable(HttpServletResponse response)

? Because we have to check the request at the beginning of CacheFilter by "isFilteredBefore" and at the end of CacheFilter by "getStatus() SC_OK".

Fernando Martins - [08/Apr/05 02:29 AM ]
instead of just doing:

if ((cacheResponse.getStatus() == HttpServletResponse.SC_OK) && isCacheable(httpRequest, cacheResponse)) {

I would rather do:

if (isCacheable(httpRequest, httpResponse)) {
                    CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper(httpResponse, fragmentRequest);
                    chain.doFilter(request, cacheResponse);
                    cacheResponse.flushBuffer();

// Only cache if the response was 200
                    if ((cacheResponse.getStatus() == HttpServletResponse.SC_OK)) {
                        //Store as the cache content the result of the response
                        cache.putInCache(key, cacheResponse.getContent(), expiresRefreshPolicy);
                        updateSucceeded = true;
                    }
                } else {
                    chain.doFilter(request, response);
                }


This way we don't use the CacheHttpServletResponseWrapper and don't have to fill up the ResponseContent, if the page is not to be cached.

Lars Torunski - [08/Apr/05 05:01 AM ]
In your code you havn't no data in httpResponse that can be checked, because any response isn't put into the cacheResponse/httpResponse until cache.doFilter is invoked.

Fernando Martins - [08/Apr/05 05:28 AM ]
Right, httpResponse has no sense at that moment, only httpRequest.
So I assume something like this:

if (isCacheable(httpRequest)) {
                    CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper(httpResponse, fragmentRequest);
                    chain.doFilter(request, cacheResponse);
                    cacheResponse.flushBuffer();

// Only cache if the response was 200
                    if ((cacheResponse.getStatus() == HttpServletResponse.SC_OK) && isCacheable(httpResponse)) {
                        //Store as the cache content the result of the response
                        cache.putInCache(key, cacheResponse.getContent(), expiresRefreshPolicy);
                        updateSucceeded = true;
                    }
                } else {
                    chain.doFilter(request, response);
                }


Fernando Martins - [08/Apr/05 05:59 AM ]
Correction (cacheResponse instead of httpResponse) :

if (isCacheable(httpRequest)) {
                    CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper(httpResponse, fragmentRequest);
                    chain.doFilter(request, cacheResponse);
                    cacheResponse.flushBuffer();

// Only cache if the response was 200
                    if ((cacheResponse.getStatus() == HttpServletResponse.SC_OK) && isCacheable(cacheResponse)) {
                        //Store as the cache content the result of the response
                        cache.putInCache(key, cacheResponse.getContent(), expiresRefreshPolicy);
                        updateSucceeded = true;
                    }
                } else {
                    chain.doFilter(request, response);
                }

Lars Torunski - [09/Apr/05 01:20 PM ]
The option can be implemented with the upcoming isCacheable(httpRequest) method.

Lars Torunski - [19/Apr/05 12:14 AM ]
Added a new option "nocache" with parameter "sessionIdInURL": Don't cache requests if session id is contained in URL.