sbs
sbs

Reputation: 1309

How do you use Plack::Middleware::Session with a Twiggy server?

I have a Twiggy based perl server:

my $app = sub { my $req = Plack::Request->new(shift); ... };
my $twiggy = Twiggy::Server->new(port => $port);
$twiggy->register_service($app);

It works fine, but now I want to add session management to it (to handle user authentication). I see there is a Plack::Middleware::Session module on CPAN, but based on the docs for it and Twiggy I don't know how to use the two together. I've reason to believe it might be possible because in my $app I'm dealing with Plack stuff.

Alternatively to using Plack::Middleware::Session, is there some other way I can easily get and set cookie values and maintain session state for authentication purposes? (Each page load requested by the user is handled in a new fork of the server.)

Upvotes: 4

Views: 312

Answers (2)

Dave Cross
Dave Cross

Reputation: 69314

The joy of PSGI is that everything plugs together the same way every time.

You expand a PSGI app with middleware, using the build function supplied by Plack::Builder.

I haven't tried it, but I expect that something like this would work:

use Twiggy::Server;
use Plack::Builder;
use Plack::Middleware::Session;

my $app = sub { my $req = Plack::Request->new(shift); ... };

$app = builder {
  enable 'Session';
  $app;
}

my $twiggy = Twiggy::Server->new(port => $port);
$twiggy->register_service($app);

Upvotes: 1

simbabque
simbabque

Reputation: 54371

You can just string it together. The builder funtion of Plack::Builder will wrap your app in a Middleware (or several). Then you just pass that as a new app to Twiggy.

use Plack::Builder;
use Twiggy::Server;

my $app = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
    my $session = $env->{'psgix.session'};
    return [
        200,
        [ 'Content-Type' => 'text/plain' ],
        [ "Hello, you've been here for ", $session->{counter}++, "th time!" ],
    ];
};

$app = builder {
    enable 'Session', store => 'File';
    $app;
};

my $twiggy = Twiggy::Server->new(port => 3000);
$twiggy->register_service($app);

AE::cv->recv;

Note that builder will return a new app, but it will not end up in $app unless you assign it. You could also just put the builder into the register_service like this:

my $twiggy = Twiggy::Server->new(port => 3000);
$twiggy->register_service(builder {
    enable 'Session', store => 'File';
    $app;
});

Or of course you could get rid of Twiggy::Server and run the twiggy command line tool or plackup with twiggy.

Upvotes: 4

Related Questions