run the code

You can start the application with plackup test.psgi or with starman --preload-app test.psgi.

NOTE: This is a conceptual HowTo and not production-ready code.

try these URLs

  • http://localhost:5000/
  • http://localhost:5000/hello
  • http://localhost:5000/coffee
  • http://localhost:5000/info
  • http://localhost:5000/user:foobar
  • http://localhost:5000/user/rename/from:foo/to:bar

the code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env perl
#
# PSGI ROUTING EXAMPLE APP
#
# (c)2018-2022 by j2l.de
# Attribution 4.0 International (CC BY 4.0)
# https://creativecommons.org/licenses/by/4.0/
#
# contact: j2l.de@sysdef.de
#

use 5.32.0;
use strict;
use warnings;
use Data::Dumper;

my $favicon = pack 'H*', map s{\s+}{}gr, do { local $/; scalar <DATA> };

# define routes
my %ROUTING = (
    '/'                                    => \&website,
    '/info'                                => \&info,
    '/hello'                               => \&helloworld,
    '/user:([^ ]*)'                        => \&user,
    '/user/rename/from:([^ ]*)/to:([^ ]*)' => \&user_rename,
    '/coffee' => sub {
        return [
            '418',
            [ 'Content-Type' => 'text/plain' ],
            ['Sorry, but I\'m a teapot.'],
        ];

    },
    '/favicon.ico' => sub {
        return [
            '200',
            [ 'Content-Type' => 'image/x-icon' ],
            [$favicon],
        ];
    },
);

my $app = sub {
    my $env = shift;

    my %PATHS = ();
    foreach my $key ( keys %ROUTING ) {
        my $path = $key;
        $path =~ s/:.*$//;
        $PATHS{$path} = {
            'route'  => $key,
            'target' => $ROUTING{$key},
        };
    }

    # routing
    my $request_uri    = $env->{'REQUEST_URI'};
    my $requested_path = $request_uri;
    $requested_path =~ s/:.*//;
    my $route = $PATHS{$requested_path};
    if ($route) {
        say " ROUTE " . $requested_path . " [" . $request_uri . "]";
        my $regex   = $route->{route};
        my @matches = ( $request_uri =~ m/$regex/ ) or return [
            '406',
            [ 'Content-Type' => 'text/html' ],
            [ '406 Bad Request: No Matches by using ' . $route->{route} ],
        ];
        $PATHS{$requested_path}{'matches'} = \@matches;
        return $route->{'target'}->( $env, $PATHS{$requested_path} );
    }

    # no route matched
    return [
        '404',
        [ 'Content-Type' => 'text/html' ],
        [ '404 Not Found: ' . $request_uri ],
    ];

};

sub user {
    my $env  = shift;
    my $data = shift;
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ 'Username is "' . ( $data->{'matches'}[0] || 'UNDEF' ) . '"' ],
    ];
}

sub user_rename {
    my $env  = shift;
    my $data = shift;
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [
            'Rename user from "'
                . ( $data->{'matches'}[0] || 'UNDEF' )
                . '" to "'
                . ( $data->{'matches'}[1] || 'UNDEF' ) . '"'
        ],
    ];
}

sub info {
    my $env = shift;
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ Dumper($env) ],
    ];
}

sub helloworld {
    my $env = shift;
    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ 'Hello World from ' . $env->{'HTTP_HOST'} . ' !' ],
    ];
}

sub website {
    my $env = shift;

    if (
        $env->{'HTTP_USER_AGENT'} =~ m/Microsoft Edge/
        )
    {
        return [
            '406',
            [ 'Content-Type' => 'text/plain' ],
            ['Get a real browser!'],
        ];
    }

    my $os = $env->{'HTTP_SEC_CH_UA_PLATFORM'};
    $os =~ s/"//g;
    return [
        '200',
        [ 'Content-Type' => 'text/html' ],
        [
            '<html>',
            '  <header>',
            '    <title>PSGI Routing Demo</title>',
            '    <link rel="shortcut icon"  href="/favicon.ico" type="image/x-icon" />',
            '  </header>',
            '  <body>',
            '    <h1>PSGI Routing Demo</h1>',
            '    A website especially for ', $os, ' User.',
            '  </body>',
            '</html>'
        ],
    ];
}

# the unpacked favicon.ico
__DATA__
0000010001002020000001002000a8100000160000002800000020000000400000000100200000000000001000000000000000000000000000000000000000000000000000004f8df2034f8df2654f8df2ce4f8df2fe4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2d64f8df2724f8df2070000000000000000000000004f8df2104f8df2bd4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2cd4f8df21a000000004f8df2024f8df2b84f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2cd4f8df2074f8df2584f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2724f8df2bc4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffb3cef9ffe8f0fdffdfeafdff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2d64f8df2f34f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff5691f3ff95bbf7ffbbd3faffbad2faff90b7f7ff538ff2ff4f8df2ff4f8df2ff4f8df2ff5e97f3ff9bbef8ff9bbef8ff6da0f4ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff9fbffffe2ecfdffffffffffffffffffffffffffffffffffd7e5fcff5993f3ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffffffffffff1f6feffadcaf9ff9fc1f8ffd8e5fcffffffffffffffffffb9d2faff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffffcfdffff6ca0f4ff4f8df2ff4f8df2ff528ff2ffd7e5fcfffffffffffbfcffff5d96f3ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff8cb4f6ffffffffffffffffff87b1f6ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff6ca0f4ffffffffffffffffff9dbff8ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff649af4ffffffffffffffffffa1c2f8ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f8feff4f8df2ff4f8df2ff4f8df2ff4f8df2ff71a3f5ffffffffffffffffff98bcf7ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbfffffffffff5f9feff4f8df2ff4f8df2ff4f8df2ff4f8df2ffa0c1f8ffffffffffffffffff7caaf5ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbffffffffffffffffff9bbef8ff508ef2ff4f8df2ff6ea1f4fff1f6fefffffffffff1f6feff5591f2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbffffffffffffffffffffffffffebf2feffe0ebfdfffcfdffffffffffffffffffff9cbff8ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ffc2d8fbffffffffffdce9fcffb0ccf9fffcfdfffffffffffffffffffffbfcffffa9c7f9ff508df2ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff5d96f3ff659bf4ff5f98f3ff4f8df2ff6299f3ff84b0f6ff83aff6ff5f97f3ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff72a4f5ffffffffffffffffff95baf7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff71a3f5fffafcfffffafcffff92b9f7ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ef4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2fe4f8df2b34f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ce4f8df24b4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2654f8df2004f8df2a64f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2bd4f8df203000000004f8df2084f8df2a64f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2b84f8df2100000000000000000000000004f8df2004f8df24b4f8df2b34f8df2ef4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2ff4f8df2f34f8df2bc4f8df2584f8df2020000000000000000c0000003800000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000001c0000003

like this post? share on: twitteremail


sysdef Avatar sysdef is the creator of this website.

published

last updated

category

hacking

tags

stay in touch.