Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie not set via plugin when running multiple apps #1449

Open
nfg opened this issue Apr 11, 2018 · 3 comments
Open

Cookie not set via plugin when running multiple apps #1449

nfg opened this issue Apr 11, 2018 · 3 comments

Comments

@nfg
Copy link
Contributor

nfg commented Apr 11, 2018

Hello! I ran into a weird case. I mount multiple apps in my PSGI file, but when I wrote a plugin that sets a cookie, it only works under one app and not the other. Here's a test case:

# file: TestPlugin.pm
use strict;
use warnings;
package TestPlugin;
use Dancer2::Plugin;
plugin_keywords test => sub {
    my $self = shift;
    $self->dsl->cookie('test_cookie' => 'rawr!!');
};
1;
# file: test.psgi
use strict;
use warnings;
use lib qw(.);

package App1;
use Dancer2;
use TestPlugin;
get '/' => sub {
    test();
    return 'Cookie: ' . response()->headers()->header('Set-Cookie');
};

package App2;
use Dancer2;
use TestPlugin;
get '/' => sub {
    test();
    return 'Cookie: ' . response()->headers()->header('Set-Cookie');
};

package main;

use Plack::Builder;

builder {
    mount '/1' => App1->to_app;
    mount '/2' => App2->to_app;
};

When I start everything via plackup test.psgi, I see the following behaviour:

➜  TestDance git:(master) ✗ curl http://localhost:5000/1
Cookie: test_cookie=rawr%21%21; HttpOnly; Path=/

# It doesn't show up here...
➜  TestDance git:(master) ✗ curl http://localhost:5000/2
Cookie: 

# But it shows up twice here
➜  TestDance git:(master) ✗ curl http://localhost:5000/1
Cookie: test_cookie=rawr%21%21; HttpOnly; Path=/, test_cookie=rawr%21%21; HttpOnly; Path=/
@nfg
Copy link
Contributor Author

nfg commented Apr 11, 2018

I've tested under Dancer2 0.205002 and Perl 5.26.0. I also saw the same thing on Dancer 0.204000. Ditto for the master branch.

@nfg
Copy link
Contributor Author

nfg commented Apr 12, 2018

I have it reproducing in a unit test (although I still have to have the plugin in another file, wrapping it in a BEGIN block didn't help). FWIW:

➜  TestDance git:(master) ✗ cat TestPlugin.pm 
use strict;
use warnings;
package TestPlugin;
use Dancer2::Plugin;

sub test {
    my ($self) = @_;
    $self->dsl->cookie($self->app->name => 'foo', http_only => 0);
};
plugin_keywords 'test';

1;

➜  TestDance git:(master) ✗ cat test2.t 
# vim: set ft=perl

use strict;
use warnings;
use lib qw(.);

use Test::More;

{
    package App1;
    use Dancer2;
    use TestPlugin;
    set logger => 'null';
    get '/' => sub {
        test();
        return 'Cookie: ' . (response()->headers()->header('Set-Cookie') // '');
    };

    package App2;
    use Dancer2;
    use TestPlugin;
    set logger => 'null';
    get '/' => sub {
        test();
        return 'Cookie: ' . (response()->headers()->header('Set-Cookie') // '');
    };
}

use Plack::Test;
use HTTP::Request::Common;

my $app1 = Plack::Test->create( App1->to_app() );
my $app2 = Plack::Test->create( App2->to_app() );

my $cookie = $app1->request(GET '/')->header('Set-Cookie');
is($cookie, 'App1=foo; Path=/', 'Got cookie from app1');
$cookie = $app2->request(GET '/')->header('Set-Cookie');
is($cookie, 'App2=foo; Path=/', 'Got cookie from app2');
$cookie = $app1->request(GET '/')->header('Set-Cookie');
is($cookie, 'App1=foo; Path=/', 'Got cookie again from app1');

done_testing();

➜  TestDance git:(master) ✗ perl test2.t 
ok 1 - Got cookie from app1
not ok 2 - Got cookie from app2
#   Failed test 'Got cookie from app2'
#   at test2.t line 38.
#          got: undef
#     expected: 'App2=foo; Path=/'
not ok 3 - Got cookie again from app1
#   Failed test 'Got cookie again from app1'
#   at test2.t line 40.
#          got: 'App2=foo; Path=/, App1=foo; Path=/'
#     expected: 'App1=foo; Path=/'
1..3
# Looks like you failed 2 tests of 3.

@nfg
Copy link
Contributor Author

nfg commented Apr 18, 2018

Ah! I'm setting the cookie incorrectly. It looks like calling

$plugin->dsl->cookie(foo => "bar")

uses the app from the DSL object, which is static. However,

$plugin->app->cookie(foo => "bar");

uses the app object on the plugin, which is app-specific.

This still strikes me as a bug, but at least there is a way to successfully set the cookie. 😃

(EDIT: It should be $plugin->app->cookie, not $plugin->cookie. I had it right in my test case, but not here.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants