251 lines
14 KiB
Plaintext
251 lines
14 KiB
Plaintext
|
|
=encoding utf8
|
|
|
|
=head1 NAME
|
|
|
|
Mojolicious::Guides::FAQ - Frequently Asked Questions
|
|
|
|
=head1 OVERVIEW
|
|
|
|
This document contains answers for the most frequently asked questions about L<Mojolicious>.
|
|
|
|
=head1 QUESTIONS
|
|
|
|
We hope these answers are to your satisfaction.
|
|
|
|
=head2 How does Mojolicious compare to other Perl web frameworks?
|
|
|
|
The short answer is "it doesn't", because we interpret the term "web framework" much more literally than others. With
|
|
the emergence of the real-time web and new technologies such as WebSockets, we are facing new challenges that go way
|
|
beyond what commonly used modules like L<LWP> were designed for. Because of this, L<Mojolicious> contains a whole new
|
|
HTTP client/server stack called L<Mojo>, which was heavily inspired by the original LWPng effort and carefully designed
|
|
with these new requirements in mind. So while some of the higher abstraction layers might look similar to other web
|
|
frameworks, it is more of a web toolkit and can even be used as the foundation for more advanced web frameworks.
|
|
|
|
=head2 Why doesn't Mojolicious have any dependencies?
|
|
|
|
We are optimizing L<Mojolicious> for user-friendliness and development speed, without compromises. While there are no
|
|
rules in L<Mojolicious::Guides::Contributing> that forbid dependencies, we do currently discourage adding non-optional
|
|
ones in favor of a faster and more painless installation process. And we do in fact already use several optional CPAN
|
|
modules such as L<Cpanel::JSON::XS>, L<EV>, L<IO::Socket::Socks>, L<IO::Socket::SSL>, L<Net::DNS::Native>, L<Plack> and
|
|
L<Role::Tiny> to provide advanced functionality if possible.
|
|
|
|
=head2 Why reinvent wheels?
|
|
|
|
Because we can make them rounder. Components specifically designed for user-friendliness and development speed are not
|
|
easy to come by. We are strong believers of the Perl mantra "There is more than one way to do it", and our quest is to
|
|
develop the best possible solutions for these two criteria.
|
|
|
|
=head2 What about backwards compatibility?
|
|
|
|
In conformance with L<Mojolicious::Guides::Contributing>, we will always deprecate a feature for 3 months, before
|
|
removing or changing it in incompatible ways between major releases. New features can however be marked as experimental
|
|
to explicitly exclude them from these rules. This gives us the necessary freedom to ensure a healthy future for
|
|
L<Mojolicious>. So, as long as you are not using anything marked experimental, untested or undocumented, you can always
|
|
count on backwards compatibility, everything else would be considered a bug. However, to completely avoid any risk of
|
|
accidental breakage, we do recommend following current best practices for version pinning with L<Carton> for production
|
|
setups.
|
|
|
|
=head2 Why not split up Mojolicious into many smaller distributions?
|
|
|
|
Because there are no advantages, it drastically increases maintenance costs and installation times without giving us
|
|
anything in return. It would only make sense if we wanted to pass ownership of a module to a new maintainer, which we
|
|
already have done in the past.
|
|
|
|
=head2 Where can i discuss my patches for Mojolicious?
|
|
|
|
We'd love to discuss your contributions to L<Mojolicious> on our official IRC channel C<#mojo> on C<chat.freenode.net>
|
|
(L<chat now!|https://webchat.freenode.net/#mojo>).
|
|
|
|
=head2 Which versions of Perl are supported by Mojolicious?
|
|
|
|
First of all, you need to be aware that according to the L<perlpolicy>, only the two most recent stable release series
|
|
of Perl are supported by the community and receive bug fixes, which are currently 5.30.x and 5.28.x. L<Mojolicious>
|
|
follows this model and fully supports these two release series. In addition we will also keep the distribution
|
|
installable (and that means passing all tests) up to a certain legacy version that the core team deems worthy of
|
|
supporting, but not specifically optimize for it, this is currently 5.16.0.
|
|
|
|
=head2 How well is Windows supported by Mojolicious?
|
|
|
|
Windows is not officially supported by L<Mojolicious>, even though we try to keep the distribution installable. There
|
|
may be serious security and/or reliability issues. Some of the more advanced features, such as
|
|
L<subprocesses|Mojo::IOLoop/"subprocess"> and the L<Hypnotoad|Mojo::Server::Hypnotoad> web server, will also require
|
|
the use of the L<Windows Subsystem for Linux|https://msdn.microsoft.com/commandline/wsl/>.
|
|
|
|
=head2 Is Perl's taint mode supported by Mojolicious?
|
|
|
|
No. There is no benefit at all to using taint mode. Modern Perl applications are much too complex to benefit from such a
|
|
naive mechanism in any meaningful way. At best it would give you a false sense of security.
|
|
|
|
=head2 Do I need to clean my environment before testing Mojolicious?
|
|
|
|
L<Mojolicious> uses many environment variables both internally and externally, notably (but not exclusively) those
|
|
starting with the prefix C<MOJO_*> and C<PLACK_ENV>. The test suite expects a clean environment; testing with a
|
|
non-standard environment is unsupported and is unlikely to succeed. Therefore when installing or upgrading
|
|
L<Mojolicious> and when running its tests, we highly recommend using an environment which does not set these variables.
|
|
|
|
=head2 Where did my file extension go?
|
|
|
|
Standard route placeholders will not match the C<.> character, however L<Mojolicious> routes automatically take file
|
|
extensions like C<.html>, remove the leading C<.>, and store the result in the C<format> stash value. This can be
|
|
useful for URL-based content negotiation, such as automatically rendering different templates based on the file
|
|
extension. See L<Mojolicious::Guides::Routing/"Formats"> for information on customizing format detection, or consider
|
|
using L<relaxed placeholders|Mojolicious::Guides::Routing/"Relaxed placeholders"> to allow matching of the C<.>
|
|
character.
|
|
|
|
=head2 Can I configure Hypnotoad from the command line?
|
|
|
|
No, you can't, L<Hypnotoad|Mojo::Server::Hypnotoad> is a bit special in this regard. Because when you initiate a zero
|
|
downtime software upgrade (hot deployment), you are only really sending a C<USR2> signal to the already running server,
|
|
and no other information can be passed along. What you can do instead, is to use a L<Mojolicious::Plugin::Config>,
|
|
L<Mojolicious::Plugin::JSONConfig> or L<Mojolicious::Plugin::NotYAMLConfig> configuration file.
|
|
|
|
# myapp.conf
|
|
{
|
|
hypnotoad => {
|
|
listen => ['http://*:8080'],
|
|
workers => 10
|
|
}
|
|
};
|
|
|
|
Or if you don't actually need zero downtime software upgrades, just use L<Mojolicious::Command::prefork> instead, which
|
|
is otherwise almost identical to Hypnotoad.
|
|
|
|
$ ./myapp.pl prefork -m production -l http://*:8080 -w 10
|
|
|
|
=head2 What does the error "...certificate verify failed" mean?
|
|
|
|
There are many variations of this error, but most of them mean that TLS certificate verification in L<Mojo::UserAgent>
|
|
failed. This usually happens for two reasons. The most common one is that the peer certificate is simply invalid. If
|
|
that's the case and you are certain that no MITM attack is being attempted, you can use the attribute
|
|
L<Mojo::UserAgent/"insecure"> or C<MOJO_INSECURE> environment variable to disable certificate verification. And if
|
|
that's not the case you might be missing the L<Mozilla::CA> module, which is often required by L<IO::Socket::SSL> to be
|
|
able to verify certificates.
|
|
|
|
=head2 What does the error "Maximum message size exceeded" mean?
|
|
|
|
To protect your applications from excessively large requests and responses, our HTTP parser has a cap after which it
|
|
will automatically stop accepting new data, and in most cases force the connection to be closed. The limit is 16MiB for
|
|
requests, and 2GiB for responses by default. You can use the attributes L<Mojolicious/"max_request_size"> and
|
|
L<Mojo::UserAgent/"max_response_size"> to change these values.
|
|
|
|
=head2 What does the error "Maximum start-line size exceeded" mean?
|
|
|
|
This is a very similar protection mechanism to the one described in the previous answer, but a little more specific. It
|
|
limits the maximum length of the start-line for HTTP requests and responses. The limit is 8KiB by default, you can use
|
|
the attribute L<Mojo::Message/"max_line_size"> or C<MOJO_MAX_LINE_SIZE> environment variable to change this value.
|
|
|
|
=head2 What does the error "Maximum header size exceeded" mean?
|
|
|
|
Almost the same as the previous answer, but this protection mechanism limits the number and maximum length of HTTP
|
|
request and response headers. The limits are 100 headers with 8KiB each by default, you can use the attributes
|
|
L<Mojo::Headers/"max_lines"> and L<Mojo::Headers/"max_line_size"> or the C<MOJO_MAX_LINES> and C<MOJO_MAX_LINE_SIZE>
|
|
environment variables to change these values.
|
|
|
|
=head2 What does the error "Maximum buffer size exceeded" mean?
|
|
|
|
This protection mechanism limits how much content the HTTP parser is allowed to buffer when parsing chunked, compressed
|
|
and multipart messages. The limit is around 256KiB by default, you can use the attribute
|
|
L<Mojo::Content/"max_buffer_size"> or C<MOJO_MAX_BUFFER_SIZE> environment variable to change this value.
|
|
|
|
=head2 What does "Your secret passphrase needs to be changed" mean?
|
|
|
|
L<Mojolicious> uses secret passphrases for security features such as signed cookies. It defaults to using
|
|
L<Mojolicious/"moniker">, which is not very secure, so we added this log message as a reminder. You can change the
|
|
passphrase with the attribute L<Mojolicious/"secrets">. Since some plugins also depend on it, you should try changing
|
|
it as early as possible in your application.
|
|
|
|
$app->secrets(['My very secret passphrase.']);
|
|
|
|
=head2 What does "Nothing has been rendered, expecting delayed response" mean?
|
|
|
|
L<Mojolicious> has been designed from the ground up for non-blocking I/O and event loops. So when a new request comes
|
|
in and no response is generated right away, it will assume that this was intentional and return control to the web
|
|
server, which can then handle other requests while waiting for events such as timers to finally generate a response.
|
|
|
|
=head2 What does "Inactivity timeout" mean?
|
|
|
|
To protect your applications from denial-of-service attacks, all connections have an inactivity timeout which limits
|
|
how long a connection may be inactive before being closed automatically. It defaults to C<40> seconds for the user
|
|
agent and C<30> seconds for all built-in web servers, and can be changed with the attributes
|
|
L<Mojo::UserAgent/"inactivity_timeout"> and L<Mojo::Server::Daemon/"inactivity_timeout"> or the
|
|
C<MOJO_INACTIVITY_TIMEOUT> environment variable. In L<Mojolicious> applications you can also use the helper
|
|
L<Mojolicious::Plugin::DefaultHelpers/"inactivity_timeout"> to change it on demand for each connection individually.
|
|
This timeout always applies, so you might have to tweak it for applications that take a long time to process a request.
|
|
|
|
=head2 What does "Premature connection close" mean?
|
|
|
|
This error message is often related to the one above, and means that the web server closed the connection before the
|
|
user agent could receive the whole response or that the user agent got destroyed, which forces all connections to be
|
|
closed immediately.
|
|
|
|
# The variable $ua goes out of scope and gets destroyed too early
|
|
Mojo::IOLoop->timer(5 => sub {
|
|
my $ua = Mojo::UserAgent->new;
|
|
$ua->get('https://mojolicious.org' => sub ($ua, $tx) {
|
|
say $tx->result->dom->at('title')->text;
|
|
});
|
|
});
|
|
|
|
=head2 What does "Worker 31842 has no heartbeat (50 seconds), restarting" mean?
|
|
|
|
As long as they are accepting new connections, worker processes of all built-in pre-forking web servers send heartbeat
|
|
messages to the manager process at regular intervals, to signal that they are still responsive. A blocking operation
|
|
such as an infinite loop in your application can prevent this, and will force the affected worker to be restarted after
|
|
a timeout. This timeout defaults to C<50> seconds and can be extended with the attribute
|
|
L<Mojo::Server::Prefork/"heartbeat_timeout"> if your application requires it.
|
|
|
|
=head2 What does "Transaction already destroyed" mean?
|
|
|
|
This error message usually appears after waiting for the results of a non-blocking operation for longer periods of
|
|
time, because the underlying connection has been closed in the meantime and the value of the attribute
|
|
L<Mojolicious::Controller/"tx"> is no longer available. While there might not be a way to prevent the connection from
|
|
getting closed, you can try to avoid this error message by keeping a reference to the transaction object that is not
|
|
weakened.
|
|
|
|
# Keep a strong reference to the transaction object
|
|
my $tx = $c->render_later->tx;
|
|
$c->ua->get_p('https://mojolicious.org')->then(sub {
|
|
$c->render(text => 'Visited mojolicious.org');
|
|
})->catch(sub ($err) {
|
|
$tx;
|
|
$c->reply->exception($err);
|
|
});
|
|
|
|
=head2 What does "Illegal character in prototype" mean?
|
|
|
|
Mojolicious assumes L<subroutine signatures|Mojolicious::Guides/"Signatures"> are enabled in documentation examples. If
|
|
the signatures feature has not been enabled in that scope, they are interpreted as L<prototypes|perlsub/"Prototypes">,
|
|
an unrelated parser feature. Mojolicious does not require signatures; if you don't want to or cannot use signatures
|
|
(which require Perl 5.20+), you can translate most signatures into a standard subroutine parameter assignment.
|
|
|
|
# With signatures feature
|
|
get '/title' => sub ($c) {
|
|
$c->ua->get('mojolicious.org' => sub ($ua, $tx) {
|
|
$c->render(data => $tx->result->dom->at('title')->text);
|
|
});
|
|
};
|
|
|
|
# Without signatures feature
|
|
get '/title' => sub {
|
|
my ($c) = @_;
|
|
$c->ua->get('mojolicious.org' => sub {
|
|
my ($ua, $tx) = @_;
|
|
$c->render(data => $tx->result->dom->at('title')->text);
|
|
});
|
|
};
|
|
|
|
=head1 MORE
|
|
|
|
You can continue with L<Mojolicious::Guides> now or take a look at the L<Mojolicious
|
|
wiki|https://github.com/mojolicious/mojo/wiki>, which contains a lot more documentation and examples by many different
|
|
authors.
|
|
|
|
=head1 SUPPORT
|
|
|
|
If you have any questions the documentation might not yet answer, don't hesitate to ask in the
|
|
L<Forum|https://forum.mojolicious.org> or the official IRC channel C<#mojo> on C<chat.freenode.net>
|
|
(L<chat now!|https://webchat.freenode.net/#mojo>).
|
|
|
|
=cut
|