CGI-Tiny
view release on metacpan or search on metacpan
lib/CGI/Tiny/Cookbook.pod view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI::Tiny;
use Path::Tiny;
use MIME::Types;
use Unicode::UTF8 qw(encode_utf8 decode_utf8);
cgi {
my $cgi = $_;
my $filename = $cgi->query_param('filename');
unless (length $filename) {
$cgi->set_response_status(404)->render(text => 'Not Found');
exit;
}
# get files from public/ next to cgi-bin/
my $public_dir = path(__FILE__)->realpath->parent->sibling('public');
my $encoded_filename = encode_utf8 $filename;
my $filepath = $public_dir->child($encoded_filename);
# ensure file exists, is readable, and is not a directory
unless (-r $filepath and !-d _) {
$cgi->set_response_status(404)->render(text => 'Not Found');
exit;
}
# ensure file path doesn't escape the public/ directory
unless ($public_dir->subsumes($filepath->realpath)) {
$cgi->set_response_status(404)->render(text => 'Not Found');
exit;
}
my $basename = decode_utf8 $filepath->basename;
my $mime = MIME::Types->new->mimeTypeOf($basename);
$cgi->set_response_type($mime->type) if defined $mime;
$cgi->set_response_disposition(attachment => $basename)->render(file => $filepath);
};
=head2 Cookies
Cookie values should only consist of ASCII characters and may not contain any
control characters, space characters, or the characters C<",;\>. More complex
strings can be encoded to UTF-8 and L<base64|MIME::Base64> for transport.
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI::Tiny;
use Unicode::UTF8 qw(decode_utf8 encode_utf8);
use MIME::Base64 qw(decode_base64 encode_base64);
cgi {
my $cgi = $_;
my $value = $cgi->param('cookie_value');
unless (defined $value) {
my $cookie = $cgi->cookie('unicode');
$value = decode_utf8 decode_base64 $cookie if defined $cookie;
}
if (defined $value) {
my $encoded_value = encode_base64 encode_utf8($value), '';
$cgi->add_response_cookie(unicode => $encoded_value, Path => '/');
$cgi->render(text => "Set cookie value: $value");
} else {
$cgi->render(text => "No cookie value set");
}
};
Data structures can be encoded to JSON and base64 for transport.
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI::Tiny;
use Cpanel::JSON::XS qw(decode_json encode_json);
use MIME::Base64 qw(decode_base64 encode_base64);
cgi {
my $cgi = $_;
my $key = $cgi->param('cookie_key');
my $hashref;
if (defined $key) {
$hashref->{$key} = $cgi->param('cookie_value');
} else {
my $cookie = $cgi->cookie('hash');
$hashref = decode_json decode_base64 $cookie if defined $cookie;
$key = (keys %$hashref)[0] if defined $hashref;
}
if (defined $hashref) {
my $encoded_value = encode_base64 encode_json($hashref), '';
$cgi->add_response_cookie(hash => $encoded_value, Path => '/');
$cgi->render(text => "Set cookie hash key $key: $hashref->{$key}");
} else {
$cgi->render(text => "No cookie value set");
}
};
=head2 Sessions
Regardless of the session mechanism, login credentials should only be sent over
HTTPS, and passwords should be stored on the server using a secure one-way
hash, such as with L<Crypt::Passphrase>.
L<Basic authentication|https://en.wikipedia.org/wiki/Basic_access_authentication>
has historically been used to provide a simplistic login session mechanism
which relies on the client to send the credentials with every subsequent
request in that browser session. However, it does not have a reliable logout or
session expiration mechanism.
Basic authentication can be handled by the CGI server itself (e.g.
L<Apache|https://httpd.apache.org/docs/2.4/howto/auth.html>), which restricts
access to a directory or location to authenticated users, and passes
L<AUTH_TYPE|CGI::Tiny/"auth_type"> and L<REMOTE_USER|CGI::Tiny/"remote_user">
with the authenticated CGI requests.
If you want to instead handle Basic authentication directly in the CGI script,
you may need to configure the CGI server to forward the C<Authorization> header
(e.g. L<Apache|https://stackoverflow.com/q/17018586/5848200>), as it is
commonly stripped from the CGI request.
( run in 1.859 second using v1.01-cache-2.11-cpan-39bf76dae61 )