views:

379

answers:

2

It seems that by default Catalyst does not output Cache-Control:, etc. headers. I know I can output them in a given controller method like this:

$c->response->headers->last_modified(time);
$c->response->headers->expires(time + $self->{cache_time});
$c->response->headers->header(cache_control => "public, max-age=$self->{cache_time}");

It'd get pretty painful doing that in each method, though! What I'd prefer is:

  • A default set of headers (expires now, last modified now, cache-control: no-cache, pragma: no-cache)
  • A way to, per-method, override the default.

Is there a good way to accomplish this?

+3  A: 

Update: Based on your response to my earlier suggestion, I decided to bite the bullet and look at the Catalyst docs. It seems to me, the place to do this is in:

  sub end : Private {
    my ( $self, $c ) = @_;

    # handle errors etc.

    if ( $c->res->body ) {
        if ( "some condition" ) {
            set_default_response_headers( $c->response->headers );
            return;
        }
        else {
            do_something_else();
            return;
        }
    }
    $c->forward( 'MyApp::View::TT' ); # render template
}

Earlier response: I do not use Catalyst, but couldn't you just write a sub for your application?

sub set_default_response_headers {
    my ($h) = @_;
    $h->last_modified(time);
    $h->expires(time + $self->{cache_time});
    $h->header(cache_control => "public, max-age=$self->{cache_time}");
    return $h;    
}

Call with set_default_response_headers( $c->response->headers ).

Sinan Ünür
Yes, I could write a sub, but then I still have to remember to call it in every method... and if it gets forgotten in any controller method, it leads to a probable bug. Seems like a rather fragile approach
derobert
+5  A: 

derobert:

Excellent question. I covered exactly this in an article for the Catalyst advent calendar.

Basically you create a stash variable that defines your cache time for the given action, and then you process it in your Root end routine. See the article for all the details.

JayK

jayk
You may want to include a short snippet in this answer.
Brad Gilbert
That wiki isn't loading for me at the moment (blank page or connection reset), but I can work with that idea. Thanks. And I can just default it to no-cache if one isn't set. Amazing this isn't built in to Catalyst; seems like every Catalyst app must have to do this!
derobert
Ok, the wiki is back up. That's a really nice approach. That really ought to be part of Catalyst, or at least a plugin....
derobert
People use Catalyst for a lot of different things and generally speaking we try to avoid adding things to Catalyst core when they aren't essential.The method is so simple that it's hardly worth creating a whole add-on for it. We usually just point folks in the direction of that wiki entry, as the whole addition is 12 lines not including comments. :-D
jayk