Peter Stuifzand

Writing Plack middleware

Let’s start with this: have you looked at Plack yet? If you haven’t you should. It’s the future of Perl web programming. It’s by far the easiest way to create web software. And the best way to start is to use one of the frameworks that were created already.

One of the nice features of frameworks based on Plack is that it’s really easy to enable kick-ass middleware by just adding one line in the configuration. The other thing is you don’t have to write many of these yourself, they’re available on CPAN.

However writing a middleware yourself isn’t really that hard. Some time ago I wrote a NoWWW middleware that removes the www. from the front of a hostname.

package WebWinkel::Middleware::NoWWW;
use strict;
use warnings;

use parent 'Plack::Middleware';
use Plack::Util;

sub call {
    my ($self, $env) = @_;

    my $host = $env->{HTTP_HOST} || $env->{SERVER_NAME};

    my $body = 'Moved permanently';

    if ($host =~ m/^www\./) {
        my $newhost = $host;
        $newhost =~ s/^www\.//;

        return [
            301,
            [ 'Location'     => 'http://'.$newhost.$env->{REQUEST_URI},
              'Content-Type' => 'text/html',
              'Content-Length' => length($body) ],
            [$body],
        ];
    }

    return $self->app->($env);
}
1;

This will remove the www. part and redirect to the same place without that prefix.

What you need to look for

Use the Plack::Middleware base class. This base class makes your module work with the Plack Framework. It also provides a way to get configuration from the ‘.psgi’ file.

Implement a call method. The call method is called by Plack and is the meat of your middleware module.

Use $env and Plack::Util to find the information you need from the environment. The environment is the information you get from the browser and the server. This is the information you need or want to change.

Return a response. By returning a response you will end the request prematurely. Sometimes this is just what you want.

Call the app. If you just want to change the environment or the response for this request, then make your changes and call the app.

You’re done. You can also write a middleware module. Some just needs to be in a middleware module even if you don’t intend to use it for other programs. They help to clean up your software.

© 2023 Peter Stuifzand