Plack Apps and Middleware

Tiny App

# app.psgi
my $page = '
<html>
<head>
  <title>PSGI rocks</title>
</head>
<body>
  <h1>PSGI rolls</h1>
</body>
</html>
';

my $app = sub { 
  [ 200, ['Content-type''text/html'], [$page]] 
};

Run it

plackup app.psgi

View it

This will start up your app by default on port 5000.

Adding Middleware

One can plug in Plack Middleware using Plack::Builder.

Debug Middleware Example

Let’s add the following snippet to the bottom of app.psgi.

use Plack::Builder;

builder {
  enable 'Debug';
  $app;
};

NOTE: To use Debug one must must meet the following criterion:

  • return a status of 200
  • Content-type of text/html or application/xhtml+xml
  • the content has a </body> tag (in front of which the Debug HTML is inserted)

The Debug Middleware adds a Debug panel to the pages with the four categories of information:

  • Environment - What $env has inside
  • Response - Status code and Content-type
  • Timer - Execution time
  • Memory - Usage

Auth::Digest Example

Plack::Middleware::Auth::Digest can be wrapped in by adding the following inside the builder block before the last line (the $app one).

  enable_if { $_[0]->{PATH_INFO} !~ m/^\/(?:public|favicon.ico)/ } 
  "Auth::Digest", 
  realm => "SecuredRealm", 
  secret => 'open_sesame',
  password_hashed => 1,
  authenticator => sub { 
    my ($username$env) = @_; 
    # This is a mockup.  You want to do something real here.
    return Digest::MD5::md5_hex("user:SecuredRealm:password");
  };

In this example, one has to authenticate when requesting any app URL that does not start with /public or /favicon.ico

The credentials to authenticate are: user and passsword. Try it out!

NOTE: I’m using the password_hashed option which means I want to return a md5_hex() of “$username:$realm:$password” which is referred to as an HA1 in the Authentication Digest world. In addition I’m using the enable_if keyword which comes from Plack::Middleware::Conditional.

Full App

Here’s the full app with the two pieces of middleware:

# app.psgi
my $page = '
<html>
<head>
  <title>PSGI rocks</title>
</head>
<body>
  <h1>PSGI rolls</h1>
</body>
</html>
';

my $app = sub { 
  [ 200, ['Content-type''text/html'], [$page]] 
};

use Plack::Builder;
use Digest::MD5;

builder {
  enable 'Debug';
  enable_if { $_[0]->{PATH_INFO} !~ m/^\/(?:public|favicon.ico)/ } 
  "Auth::Digest", 
  realm => "SecuredRealm", 
  secret => 'open_sesame',
  password_hashed => 1,
  authenticator => sub { 
    my ($username$env) = @_; 
    # This is a mockup.  You want to do something real here.
    return Digest::MD5::md5_hex("user:SecuredRealm:password");
  };
  $app;
};
My tags:
 
Popular tags:
 
Powered by MojoMojo