view release on metacpan or search on metacpan
8.34 2020-03-16
- Removed experimental status from proxy->get_p, proxy->post_p and proxy->start_p helpers in
Mojolicious::Plugin::DefaultHelpers.
- Removed experimental status from compress and min_compress_size attributes in Mojolicious::Renderer.
- Removed experimental status from high_water_mark attribute in Mojo::IOLoop::Stream.
- Removed experimental status from respond method in Mojolicious::Renderer.
- Removed experimental status from bytes_waiting and can_write methods in Mojo::IOLoop::Stream.
- Removed experimental status from dehop method in Mojo::Headers.
- Removed experimental status from scope_guard function in Mojo::Util.
- Improved size check in Mojolicious::Validator to only require one argument.
- Fixed Mojolicious::Validator to also validate empty string values instead of ignoring them. This behaviour had
caused a lot of confusion in the past.
- Fixed plugin generator not to use an __END__ section.
8.33 2020-02-11
- Added EXPERIMENTAL humanize_bytes function to Mojo::Util. (kraih, coolo)
- Added EXPERIMENTAL humanize_bytes method to Mojo::ByteStream.
- Updated Future::AsyncAwait requirement to 0.36 for better tests. (ilmari)
8.32 2020-01-18
- Changed experimental -async flag to -async_await in Mojo::Base, because of a Perl quirk that Future::AsyncAwait
lib/Mojolicious/Guides/Growing.pod view on Meta::CPAN
=head2 State keeping
Sessions in L<Mojolicious> pretty much just work out of the box once you start using the method
L<Mojolicious::Controller/"session">, there is no setup required, but we suggest setting a more secure passphrase with
L<Mojolicious/"secrets">.
app->secrets(['Mojolicious rocks']);
This passphrase is used by the HMAC-SHA256 algorithm to make signed cookies tamper resistant and can be changed at any
time to invalidate all existing sessions.
$c->session(user => 'sebastian');
my $user = $c->session('user');
By default all sessions expire after one hour, for more control you can use the C<expiration> session value to set an
expiration date in seconds from now.
$c->session(expiration => 3600);
And the whole session can be deleted by using the C<expires> session value to set an absolute expiration date in the
lib/Mojolicious/Guides/Rendering.pod view on Meta::CPAN
% end
</body>
</html>
The helpers L<Mojolicious::Plugin::DefaultHelpers/"flash"> and L<Mojolicious::Plugin::DefaultHelpers/"redirect_to"> are
often used together to prevent double form submission, allowing users to receive a confirmation message that will
vanish if they decide to reload the page they've been redirected to.
=head2 Form validation
You can use L<Mojolicious::Plugin::DefaultHelpers/"validation"> to validate C<GET> and C<POST> parameters submitted to
your application. All unknown fields will be ignored by default, so you have to decide which should be
L<required|Mojolicious::Validator::Validation/"required"> or L<optional|Mojolicious::Validator::Validation/"optional">
before you can perform checks on their values. Every check is performed right away, so you can use the results
immediately to build more advanced validation logic with methods like L<Mojolicious::Validator::Validation/"is_valid">.
use Mojolicious::Lite -signatures;
get '/' => sub ($c) {
# Check if parameters have been submitted
lib/Mojolicious/Guides/Rendering.pod view on Meta::CPAN
%= text_field 'number'
%= submit_button
% end
</body>
</html>
=head2 Cross-site request forgery
CSRF is a very common attack on web applications that trick your logged in users to submit forms they did not intend to
send, with something as mundane as a link. All you have to do, to protect your users from this, is to add an additional
hidden field to your forms with L<Mojolicious::Plugin::TagHelpers/"csrf_field">, and validate it with
L<Mojolicious::Validator::Validation/"csrf_protect">.
use Mojolicious::Lite -signatures;
get '/' => {template => 'target'};
post '/' => sub ($c) {
# Check CSRF token
my $v = $c->validation;
lib/Mojolicious/Guides/Routing.pod view on Meta::CPAN
$r->get('/welcome')->to('foo#welcome');
$r->post('/bye')->to('foo#bye');
}
1;
Post-processing the response to add or remove headers is a very common use.
# Make sure static files are cached
$app->hook(after_static => sub ($c) {
$c->res->headers->cache_control('max-age=3600, must-revalidate');
});
# Remove a default header
$app->hook(after_dispatch => sub ($c) {
$c->res->headers->remove('Server');
});
Same for pre-processing the request.
# Choose template variant based on request headers
lib/Mojolicious/Plugin/DefaultHelpers.pm view on Meta::CPAN
%= url_with 'named', foo => 'bar', baz => 'yada'
Does the same as L</"url_for">, but inherits query parameters from the current request.
%= url_with->query({page => 2})
=head2 validation
my $v = $c->validation;
Get L<Mojolicious::Validator::Validation> object for current request to validate file uploads as well as C<GET> and
C<POST> parameters extracted from the query string and C<application/x-www-form-urlencoded> or C<multipart/form-data>
message body. Parts of the request body need to be loaded into memory to parse C<POST> parameters, so you have to make
sure it is not excessively large. There's a 16MiB limit for requests by default.
# Validate GET/POST parameter
my $v = $c->validation;
$v->required('title', 'trim')->size(3, 50);
my $title = $v->param('title');
# Validate file upload
lib/Mojolicious/Validator.pm view on Meta::CPAN
use Mojolicious::Validator;
my $validator = Mojolicious::Validator->new;
my $v = $validator->validation;
$v->input({foo => 'bar'});
$v->required('foo')->like(qr/ar$/);
say $v->param('foo');
=head1 DESCRIPTION
L<Mojolicious::Validator> validates values for L<Mojolicious>.
=head1 CHECKS
These validation checks are available by default.
=head2 equal_to
$v = $v->equal_to('foo');
String value needs to be equal to the value of another field.
lib/Mojolicious/Validator/Validation.pm view on Meta::CPAN
my $token = $v->csrf_token;
$v = $v->csrf_token('fa6a08...');
CSRF token.
=head2 input
my $input = $v->input;
$v = $v->input({foo => 'bar', baz => [123, 'yada']});
Data to be validated.
=head2 output
my $output = $v->output;
$v = $v->output({foo => 'bar', baz => [123, 'yada']});
Validated data.
=head2 topic
my $topic = $v->topic;
$v = $v->topic('foo');
Name of field currently being validated.
=head2 validator
my $v = $v->validator;
$v = $v->validator(Mojolicious::Validator->new);
L<Mojolicious::Validator> object this validation belongs to.
=head1 METHODS
lib/Mojolicious/Validator/Validation.pm view on Meta::CPAN
Change validation L</"topic"> and apply filters. All filters from L<Mojolicious::Validator/"FILTERS"> are supported.
# Trim value and check size
$v->optional('user', 'trim')->size(1, 15);
=head2 param
my $value = $v->param;
my $value = $v->param('foo');
Access validated values, defaults to the current L</"topic">. If there are multiple values sharing the same name, and
you want to access more than just the last one, you can use L</"every_param">.
# Get value right away
my $user = $v->optional('user')->size(1, 15)->param;
=head2 passed
my $names = $v->passed;
Return an array reference with all names for values that passed validation.
lib/Mojolicious/resources/public/mojo/bootstrap/bootstrap.css view on Meta::CPAN
@charset "UTF-8";/*!
* Bootstrap v5.3.2 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff...
/*# sourceMappingURL=bootstrap.min.css.map */
lib/Mojolicious/resources/public/mojo/bootstrap/bootstrap.min.css.map view on Meta::CPAN
{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_root.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_color-mode.scss","../../scss/_reboot.scss","../../scss/mixins/_border-radius.scss","../../scss...
lib/Mojolicious/resources/public/mojo/highlight.js/highlight.min.js view on Meta::CPAN
beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{
beginKeywords:"extends"},c.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,
end:/[\{;]/,excludeEnd:!0,contains:[c.inherit(c.TITLE_MODE,{begin:o}),"self",R]
},{begin:"(get|set)\\s+(?="+o+"\\()",end:/{/,keywords:"get set",
contains:[c.inherit(c.TITLE_MODE,{begin:o}),{begin:/\(\)/},R]},{begin:/\$[(.]/}]
}}}());hljs.registerLanguage("sql",function(){"use strict";return function(e){
var t=e.COMMENT("--","$");return{name:"SQL",case_insensitive:!0,
illegal:/[<>{}*]/,contains:[{
beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release ...
end:/;/,endsWithParent:!0,keywords:{$pattern:/[\w\.]+/,
keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always ana...
literal:"true false null unknown",
built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"
},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{
className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{
className:"string",begin:"`",end:"`"
},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]
},e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]}}}());hljs.registerLanguage("diff",function(){"use strict";return function(e){return{
name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,
variants:[{begin:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{
begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{
t/mojolicious/dispatcher_lite_app.t view on Meta::CPAN
# Cleared response for /res.txt
hook before_routes => sub {
my $c = shift;
return unless $c->req->url->path->contains('/res.txt') && $c->param('route');
$c->tx->res(Mojo::Message::Response->new);
};
# Set additional headers for static files
hook after_static => sub {
my $c = shift;
$c->res->headers->cache_control('max-age=3600, must-revalidate');
};
# Make controller available as $_
hook around_action => sub {
my ($next, $c) = @_;
local $_ = $c;
return $next->();
};
# Plugin for rendering return values
t/mojolicious/dispatcher_lite_app.t view on Meta::CPAN
# Allow rendering of return value
under '/' => {return => 1} => sub {1};
# Return and render argument
get '/' => sub { return pop } => 'works';
my $t = Test::Mojo->new;
subtest 'Normal route' => sub {
$t->get_ok('/')->status_is(200)->header_isnt('Cache-Control' => 'max-age=3600, must-revalidate')->content_is('works');
};
subtest 'Normal static file' => sub {
$t->get_ok('/test.txt')
->status_is(200)
->header_is('Cache-Control' => 'max-age=3600, must-revalidate')
->content_is("Normal static file!\n");
};
subtest 'Override static file' => sub {
$t->get_ok('/hello.txt')->status_is(200)->content_is('Custom static file works!');
};
subtest 'render_later from before_dispatch' => sub {
$t->get_ok('/hello-delay.txt')->status_is(200)->content_is('Delayed!');
};
subtest 'Custom dispatcher' => sub {
$t->get_ok('/custom?a=works+too')->status_is(205)->content_is('works too');
};
subtest 'Static file' => sub {
$t->get_ok('/res.txt')
->status_is(200)
->header_is('Cache-Control' => 'max-age=3600, must-revalidate')
->content_is("Static response!\n");
};
subtest ' Custom response' => sub {
$t->get_ok('/res.txt?route=1')
->status_is(202)
->header_isnt('Cache-Control' => 'max-age=3600, must-revalidate')
->content_is('Custom response!');
};
subtest 'Conditional response' => sub {
$t->get_ok('/res.txt?route=1&res=1')
->status_is(201)
->header_isnt('Cache-Control' => 'max-age=3600, must-revalidate')
->content_is('Conditional response!');
};
subtest 'Another custom dispatcher' => sub {
$t->get_ok('/custom_too')
->status_is(200)
->header_isnt('Cache-Control' => 'max-age=3600, must-revalidate')
->content_is('this works too');
};
subtest 'First wrapper' => sub {
$t->get_ok('/wrap')->status_is(200)->content_is('Wrapped!');
};
subtest 'Second wrapper' => sub {
$t->get_ok('/wrap/again')->status_is(200)->content_is('Wrapped again!');
};