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 |