Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

Make Catalyst NOT reset a cookie on a per action basis

 

 

Catalyst users RSS feed   Index | Next | Previous | View Threaded


steve at prodhub

Aug 16, 2009, 11:59 AM

Post #1 of 6 (1147 views)
Permalink
Make Catalyst NOT reset a cookie on a per action basis

OBJECTIVE:
On a per action basis, have Catalyst NOT reset cookies it finds using
'Session::State::Cookie'.

PROBLEM:
Images are dispatched from a database (and therefore not statically
served). The rest of the app requires a cookie to be set, but for
images coming from a specific action, a cookie should NOT be set
because the browser will not cache an image with a cookie (it is
immediately stale). The result is no caching and a hit to the database
every time an image is requested.

WHAT I CAN SEE:
Catalyst engine calls "finalize_cookies" which resets every cookie it
finds. This takes place before the 'begin' method and the 'Set-Cookie'
header has already been dispatched. Therefore removing that header in
'begin' does nothing. If the original request did not present a
cookie, then Catalyst does not regurgitate the cookie and everything
works great.

Thanks for any guidance. It'd be great of there's a solution that
doesn't require constraining the cookie path.

Appreciatively,

Steve Kleiman
Los Angeles, California


bobtfish at bobtfish

Aug 17, 2009, 2:33 PM

Post #2 of 6 (1067 views)
Permalink
Re: Make Catalyst NOT reset a cookie on a per action basis [In reply to]

On 16 Aug 2009, at 19:59, Steve Kleiman wrote:
> WHAT I CAN SEE:
> Catalyst engine calls "finalize_cookies" which resets every cookie
> it finds. This takes place before the 'begin' method and the 'Set-
> Cookie' header has already been dispatched. Therefore removing that
> header in 'begin' does nothing. If the original request did not
> present a cookie, then Catalyst does not regurgitate the cookie and
> everything works great.
>
> Thanks for any guidance. It'd be great of there's a solution that
> doesn't require constraining the cookie path.

How about:

after 'finalize_cookies' => sub {
my $c = shift;
$c->res->cookies({}) if $c->stash->{no_cookies};
};

in your MyApp.pm, then just arrange for things to set $c->stash-
>{no_cookies}?

Cheers
t0m

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


steve at prodhub

Aug 17, 2009, 5:19 PM

Post #3 of 6 (1069 views)
Permalink
Re: Make Catalyst NOT reset a cookie on a per action basis [In reply to]

Thanks for taking a look. I thought I had it isolated but seems not.
Tried what you suggested below but the instigator of the cookie
happens at a different juncture.

The instigator for a 'Catalyst::Plugin::Session' cookie being set is
'Session::prepare_action'. The method calls 'sessionid' which
ultimately invokes the resetting of the cookie.

> sub prepare_action {
> my $c = shift;
>
> if ( $c->config->{session}{flash_to_stash}
> and $c->sessionid
> and my $flash_data = $c->flash )
> {
> @{ $c->stash }{ keys %$flash_data } = values %$flash_data;
> }
>
> $c->maybe::next::method(@_);
> }

So a more refined question would be, is there a way to wrap only
'Session::prepare_action' whilst not wrapping all the other
'prepare_action' methods? I've tried the following but have had no luck:
> before 'prepare_action' => sub { ... }
> before 'Session::prepare_action' => sub { ... }
> before 'Catalyst::Plugin::Session::prepare_action' => sub { ... }

Thanks for the help....

-steve



On Aug 17, 2009, at 2:33 PM, Tomas Doran wrote:

>
> On 16 Aug 2009, at 19:59, Steve Kleiman wrote:
>> WHAT I CAN SEE:
>> Catalyst engine calls "finalize_cookies" which resets every cookie
>> it finds. This takes place before the 'begin' method and the 'Set-
>> Cookie' header has already been dispatched. Therefore removing that
>> header in 'begin' does nothing. If the original request did not
>> present a cookie, then Catalyst does not regurgitate the cookie and
>> everything works great.
>>
>> Thanks for any guidance. It'd be great of there's a solution that
>> doesn't require constraining the cookie path.
>
> How about:
>
> after 'finalize_cookies' => sub {
> my $c = shift;
> $c->res->cookies({}) if $c->stash->{no_cookies};
> };
>
> in your MyApp.pm, then just arrange for things to set $c->stash-
> >{no_cookies}?
>
> Cheers
> t0m


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


bobtfish at bobtfish

Aug 17, 2009, 5:50 PM

Post #4 of 6 (1067 views)
Permalink
Re: Make Catalyst NOT reset a cookie on a per action basis [In reply to]

On 18 Aug 2009, at 01:19, Steve Kleiman wrote:

> Thanks for taking a look. I thought I had it isolated but seems
> not. Tried what you suggested below but the instigator of the
> cookie happens at a different juncture.
>
> The instigator for a 'Catalyst::Plugin::Session' cookie being set
> is 'Session::prepare_action'. The method calls 'sessionid' which
> ultimately invokes the resetting of the cookie.

Right.. But you then clear the cookie at the end of the hit, problem
solved?
>
> So a more refined question would be, is there a way to wrap only
> 'Session::prepare_action' whilst not wrapping all the other
> 'prepare_action' methods? I've tried the following but have had no
> luck:
>> before 'prepare_action' => sub { ... }
>> before 'Session::prepare_action' => sub { ... }
>> before 'Catalyst::Plugin::Session::prepare_action' => sub { ... }
>
> Thanks for the help....


Sure - Class::MOP::Class->initialize('Catalyst::Plugin::Session')-
>add_before_modifier iirc. Also - when you say 'wrap' - a before
modifier won't wrap a method - the method _always_ runs.

Also, monkeypatching like this is a bad idea, as it has global effect
(your entire perl interpreter).

Why doesn't the initial solution solve your problem, by clearing the
troublesome cookie (so the browser never sees it) at the end of the hit.

Cheers
t0m


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


steve at prodhub

Aug 17, 2009, 7:21 PM

Post #5 of 6 (1063 views)
Permalink
Re: Make Catalyst NOT reset a cookie on a per action basis [In reply to]

Thanks for getting back again.

Weird. I didn't dig in too deep to figure why this is, but it is.

This was what was suggested but didn't work:
> $c->res->cookies({})

However this did:
> $c->res->headers->remove_header('Set-Cookie')


Thank you, Tomas.

-steve


On Aug 17, 2009, at 5:50 PM, Tomas Doran wrote:

>
> On 18 Aug 2009, at 01:19, Steve Kleiman wrote:
>
>> Thanks for taking a look. I thought I had it isolated but seems
>> not. Tried what you suggested below but the instigator of the
>> cookie happens at a different juncture.
>>
>> The instigator for a 'Catalyst::Plugin::Session' cookie being set
>> is 'Session::prepare_action'. The method calls 'sessionid' which
>> ultimately invokes the resetting of the cookie.
>
> Right.. But you then clear the cookie at the end of the hit, problem
> solved?
>>
>> So a more refined question would be, is there a way to wrap only
>> 'Session::prepare_action' whilst not wrapping all the other
>> 'prepare_action' methods? I've tried the following but have had no
>> luck:
>>> before 'prepare_action' => sub { ... }
>>> before 'Session::prepare_action' => sub { ... }
>>> before 'Catalyst::Plugin::Session::prepare_action' => sub { ... }
>>
>> Thanks for the help....
>
>
> Sure - Class::MOP::Class->initialize('Catalyst::Plugin::Session')-
> >add_before_modifier iirc. Also - when you say 'wrap' - a before
> modifier won't wrap a method - the method _always_ runs.
>
> Also, monkeypatching like this is a bad idea, as it has global
> effect (your entire perl interpreter).
>
> Why doesn't the initial solution solve your problem, by clearing the
> troublesome cookie (so the browser never sees it) at the end of the
> hit.
>
> Cheers
> t0m


_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/


bobtfish at bobtfish

Aug 18, 2009, 12:31 AM

Post #6 of 6 (1058 views)
Permalink
Re: Make Catalyst NOT reset a cookie on a per action basis [In reply to]

On 18 Aug 2009, at 03:21, Steve Kleiman wrote:

> Thanks for getting back again.
>
> Weird. I didn't dig in too deep to figure why this is, but it is.
>
> This was what was suggested but didn't work:
>> $c->res->cookies({})
>
> However this did:
>> $c->res->headers->remove_header('Set-Cookie')

Aha :)

My suggestion was totally off the top of my head, without looking at
any of the documentation (as they usually are), ergo the getting it
wrong - I was expecting you to fiddle to find the right method if it
didn't 'just work'. :)

Glad your issue is fixed.

I'd be totally up for making 'do not send cookies' more supported /
elegant in the -Session code, but I can't think of a nicer interface
than that ^^ (probably as I haven't thought about it to hard).
Suggestions in the form of patches welcome..

Cheers
t0m

_______________________________________________
List: Catalyst [at] lists
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst [at] lists/
Dev site: http://dev.catalyst.perl.org/

Catalyst users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.