Skip to content

Commit

Permalink
make it easier to use systemd for socket activation
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jul 4, 2017
1 parent a8af0f5 commit 8c63cdf
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 19 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,8 +1,10 @@

7.35 2017-07-04
7.35 2017-07-05
- Removed deprecated watch attribute from Mojo::Server::Morbo.
- Added spare attribute to Mojo::Server::Prefork.
- Added -s option to prefork command.
- Added fd option to Mojo::IOLoop::Server::listen.
- Added fd parameter to Mojo::Server::Daemon::listen.
- Added spare setting to Hypnotoad.
- Increased default graceful_timeout from 20 to 60 seconds and
heartbeat_timeout from 20 to 30 seconds in Mojo::Server::Prefork.
Expand Down
8 changes: 7 additions & 1 deletion lib/Mojo/IOLoop/Server.pm
Expand Up @@ -45,7 +45,7 @@ sub listen {
# Reuse file descriptor
my $handle;
my $class = $path ? 'IO::Socket::UNIX' : 'IO::Socket::IP';
if (defined $fd) {
if (defined($fd //= $args->{fd})) {
$handle = $class->new_from_fd($fd, 'r')
or croak "Can't open file descriptor $fd: $!";
}
Expand Down Expand Up @@ -223,6 +223,12 @@ Local address to listen on, defaults to C<0.0.0.0>.
Maximum backlog size, defaults to C<SOMAXCONN>.
=item fd
fd => 3
File descriptor with an already prepared listen socket.
=item path
path => '/tmp/myapp.sock'
Expand Down
18 changes: 12 additions & 6 deletions lib/Mojo/Server/Daemon.pm
Expand Up @@ -171,12 +171,9 @@ sub _listen {
croak qq{Invalid listen location "$listen"}
unless $proto eq 'http' || $proto eq 'https' || $proto eq 'http+unix';

my $query = $url->query;
my $options = {
backlog => $self->backlog,
single_accept => $query->param('single_accept'),
reuse => $query->param('reuse')
};
my $query = $url->query;
my $options = {backlog => $self->backlog};
$options->{$_} = $query->param($_) for qw(fd single_accept reuse);
if ($proto eq 'http+unix') { $options->{path} = $url->host }
else {
if ((my $host = $url->host) ne '*') { $options->{address} = $host }
Expand Down Expand Up @@ -370,6 +367,9 @@ C<http://0.0.0.0:3000>).
# Listen on UNIX domain socket "/tmp/myapp.sock" (percent encoded slash)
$daemon->listen(['http+unix://%2Ftmp%2Fmyapp.sock']);
# File descriptor, as used by systemd
$daemon->listen(['http://127.0.0.1?fd=3']);
# Allow multiple servers to use the same port (SO_REUSEPORT)
$daemon->listen(['http://*:8080?reuse=1']);
Expand Down Expand Up @@ -411,6 +411,12 @@ Path to the TLS cert file, defaults to a built-in test certificate.
TLS cipher specification string. For more information about the format see
L<https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-STRINGS>.
=item fd
fd=3
File descriptor with an already prepared listen socket.
=item key
key=/etc/tls/server.key
Expand Down
44 changes: 33 additions & 11 deletions t/mojo/daemon.t
Expand Up @@ -7,6 +7,7 @@ BEGIN {

use Test::More;
use FindBin;
use IO::Socket::INET;
use Mojo;
use Mojo::File 'path';
use Mojo::IOLoop;
Expand Down Expand Up @@ -120,31 +121,38 @@ $app->log->level('fatal');

$app->routes->post(
'/chunked' => sub {
my $self = shift;
my $c = shift;

my $params = $self->req->params->to_hash;
my $params = $c->req->params->to_hash;
my @chunks;
for my $key (sort keys %$params) { push @chunks, $params->{$key} }

my $cb;
$cb = sub {
my $self = shift;
my $c = shift;
$cb = undef unless my $chunk = shift @chunks || '';
$self->write_chunk($chunk, $cb);
$c->write_chunk($chunk, $cb);
};
$self->$cb;
$c->$cb;
}
);

my ($local_address, $local_port, $remote_address, $remote_port);
$app->routes->post(
'/upload' => sub {
my $self = shift;
$local_address = $self->tx->local_address;
$local_port = $self->tx->local_port;
$remote_address = $self->tx->remote_address;
$remote_port = $self->tx->remote_port;
$self->render(data => $self->req->upload('file')->slurp);
my $c = shift;
$local_address = $c->tx->local_address;
$local_port = $c->tx->local_port;
$remote_address = $c->tx->remote_address;
$remote_port = $c->tx->remote_port;
$c->render(data => $c->req->upload('file')->slurp);
}
);

$app->routes->any(
'/port' => sub {
my $c = shift;
$c->render(text => $c->req->url->to_abs->port);
}
);

Expand Down Expand Up @@ -325,6 +333,20 @@ ok !$tx->keep_alive, 'will not be kept alive';
is $tx->res->code, 200, 'right status';
is $tx->res->body, 'Whatever!', 'right content';

# File descriptor
my $listen = IO::Socket::INET->new(Listen => 5, LocalAddr => '127.0.0.1');
my $fd = fileno $listen;
$daemon = Mojo::Server::Daemon->new(
app => $app,
listen => ["http://127.0.0.1?fd=$fd"],
silent => 1
)->start;
$port = $listen->sockport;
is $daemon->ports->[0], $port, 'same port';
$tx = $ua->get("http://127.0.0.1:$port/port");
is $tx->res->code, 200, 'right status';
is $tx->res->body, $port, 'right content';

# No TLS support
eval {
Mojo::Server::Daemon->new(listen => ['https://127.0.0.1'], silent => 1)
Expand Down

0 comments on commit 8c63cdf

Please sign in to comment.