lemonldap-ng/fastcgi-server/sbin/llng-fastcgi-server

319 lines
7.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl
2016-02-04 23:10:17 +01:00
use Plack::Runner;
use strict;
use warnings;
use POSIX;
2016-12-29 21:34:40 +01:00
use Getopt::Long;
2017-01-09 22:54:06 +01:00
use Lemonldap::NG::Handler::Main::Reload;
2016-02-04 23:10:17 +01:00
2019-02-12 18:21:38 +01:00
our $VERSION = '2.1.0';
2016-02-04 23:10:17 +01:00
2016-12-29 21:34:40 +01:00
our (
$foreground, $engine, $nproc, $pidFile,
$socket, $user, $listen, $group,
$procmanager, $customFunctionsFile, %plackOptions
2016-12-29 21:34:40 +01:00
);
my %_apps;
2016-02-04 23:10:17 +01:00
2016-06-09 13:45:08 +02:00
$SIG{'PIPE'} = 'IGNORE';
$ENV{LLNG_DEFAULTLOGGER} ||= 'Lemonldap::NG::Common::Logger::Syslog';
2016-06-09 13:45:08 +02:00
2016-12-29 21:34:40 +01:00
$foreground = 0;
$engine ||= $ENV{ENGINE} || 'FCGI';
$nproc ||= $ENV{NPROC} || 7;
$pidFile ||= $ENV{PID} || '__FASTCGISOCKDIR__/llng-fastcgi.pid';
$socket ||= $ENV{SOCKET} || '__FASTCGISOCKDIR__/llng-fastcgi.sock';
$listen ||= $ENV{LISTEN} || undef;
2016-12-29 21:34:40 +01:00
$user ||= $ENV{USER};
$group ||= $ENV{GROUP};
$customFunctionsFile ||= $ENV{CUSTOM_FUNCTIONS_FILE};
# If the user specified any PM_ constrains, run under ::Constrained
$procmanager = "FCGI::ProcManager::Constrained" if grep /^PM_/, keys %ENV;
2016-12-29 21:34:40 +01:00
#Getopt::Long::Configure ("bundling_values");
GetOptions(
'foreground' => \$foreground,
'engine|e=s' => \$engine,
'proc|n=s' => \$nproc,
'pid|p=s' => \$pidFile,
'socket|s=s' => \$socket,
'listen|l=s' => \$listen,
2016-12-29 21:34:40 +01:00
'user|u=s' => \$user,
'group|g=s' => \$group,
'customFunctionsFile|f=s' => \$customFunctionsFile,
'plackOptions=s' => \%plackOptions,
);
2016-02-04 23:10:17 +01:00
2016-12-29 21:34:40 +01:00
if ($group) {
2019-06-19 21:47:07 +02:00
my $grp = getgrnam($group) or die "Can't change gid to $group";
POSIX::setgid($grp) or die "setgid: $!";
2016-02-04 23:10:17 +01:00
}
2016-12-29 21:34:40 +01:00
if ($user) {
my $uid = getpwnam($user) or die "Can't change uid to $user";
POSIX::setuid($uid) or die "setuid: $!";
2016-02-04 23:10:17 +01:00
}
unless ($>) {
die "Refuse to run as root. Aborting";
}
2016-12-29 21:34:40 +01:00
if ($customFunctionsFile) {
eval { require $customFunctionsFile };
2016-06-09 13:45:08 +02:00
die $@ if ($@);
}
2016-02-04 23:10:17 +01:00
my %builder = (
2016-07-16 08:05:36 +02:00
reload => sub {
2017-02-11 08:47:22 +01:00
return Lemonldap::NG::Handler::Server::Nginx->reload();
2016-07-16 08:05:36 +02:00
},
2016-02-11 13:09:53 +01:00
status => sub {
2017-02-11 08:47:22 +01:00
return Lemonldap::NG::Handler::Server::Nginx->status();
2016-02-11 13:09:53 +01:00
},
2016-02-04 23:10:17 +01:00
manager => sub {
require Lemonldap::NG::Manager;
return Lemonldap::NG::Manager->run( {} );
},
cgi => sub {
2016-02-04 23:10:17 +01:00
require CGI::Emulate::PSGI;
require CGI::Compile;
return sub {
my $script = $_[0]->{SCRIPT_FILENAME};
return $_apps{$script}->(@_) if ( $_apps{$script} );
$_apps{$script} =
CGI::Emulate::PSGI->handler( CGI::Compile->compile($script) );
return $_apps{$script}->(@_);
};
2016-02-04 23:10:17 +01:00
},
2017-01-09 22:54:06 +01:00
psgi => sub {
return sub {
my $script = $_[0]->{SCRIPT_FILENAME};
return $_apps{$script}->(@_) if ( $_apps{$script} );
$_apps{$script} = do $script;
2018-02-08 21:25:02 +01:00
unless ( $_apps{$script} and ref $_apps{$script} ) {
die "Unable to load $_[0]->{SCRIPT_FILENAME}";
}
2017-01-09 22:54:06 +01:00
return $_apps{$script}->(@_);
}
2017-01-09 22:54:06 +01:00
},
2016-02-04 23:10:17 +01:00
);
require Lemonldap::NG::Handler::Server::Nginx;
$_apps{handler} = Lemonldap::NG::Handler::Server::Nginx->run( {} );
2016-02-04 23:10:17 +01:00
my $app = sub {
2021-07-02 12:17:04 +02:00
$SIG{'PIPE'} = sub {
print STDERR "Got a PIPE signal";
};
2016-02-04 23:10:17 +01:00
my $type = $_[0]->{LLTYPE} || 'handler';
return $_apps{$type}->(@_) if ( defined $_apps{$type} );
if ( defined $builder{$type} ) {
$_apps{$type} = $builder{$type}->();
return $_apps{$type}->(@_);
}
die "Unknown PSGI type $type";
};
# Hook for customFunctions initialization
2017-02-10 12:05:42 +01:00
Lemonldap::NG::Handler::Main->onReload(
2017-01-09 22:54:06 +01:00
bless( {}, 'Lemonldap::NG::Handler::FastCGI::Loader' ),
2017-02-18 15:36:48 +01:00
'loadCustomHandlers' );
2017-01-09 22:54:06 +01:00
my $server = Plack::Runner->new();
$server->parse_options(
2018-02-08 21:25:02 +01:00
'-s' => $engine,
'-E' => 'deployment',
'--pid' => $pidFile,
'--nproc' => $nproc,
'--socket' => $socket,
( $listen ? ( '--listen', $listen ) : () ),
2017-01-09 22:54:06 +01:00
'--proc-title' => 'llng-fastcgi-server',
( $foreground ? () : '--daemonize' ),
'--no-default-middleware',
( $procmanager ? ( '--manager', $procmanager ) : () ),
2017-01-09 22:54:06 +01:00
%plackOptions,
);
$server->run($app);
package Lemonldap::NG::Handler::FastCGI::Loader;
2016-12-29 21:34:40 +01:00
# Load configuration and look if custom handlers have been defined
2017-02-18 15:36:48 +01:00
sub loadCustomHandlers {
2017-01-09 22:54:06 +01:00
my ( $obj, $conf ) = @_;
2017-03-06 13:25:18 +01:00
foreach my $lltype ( keys %{ $conf->{nginxCustomHandlers} || {} } ) {
2016-12-29 21:34:40 +01:00
my $v = $conf->{nginxCustomHandlers}->{$lltype};
2017-01-02 07:06:26 +01:00
if ( $v =~ m#[/\\\.]# ) {
2016-12-29 21:34:40 +01:00
eval { require $v; };
2017-01-02 07:06:26 +01:00
}
else {
eval "use $v";
}
if ($@) {
print STDERR "Unable to load $v, skipping: $@\n";
next;
2016-12-29 21:34:40 +01:00
}
$builder{$lltype} = sub {
require $v;
return $v->run( {} );
};
}
2017-07-17 20:36:07 +02:00
return 1;
2016-12-29 21:34:40 +01:00
}
2016-02-07 09:32:40 +01:00
__END__
2016-02-04 23:10:17 +01:00
2016-02-07 09:32:40 +01:00
=head1 NAME
=encoding utf8
llng-fastcgi-server - FastCGI server used to provide Lemonldap::NG services to
Nginx
=head1 SYNOPSIS
# Start server listening to /run/llng.sock with 10 process
llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -n 10
=head1 DESCRIPTION
llng-fastcgi-server has been designed provides Lemonldap::NG services to Nginx.
Portal, manager and handler will be compiled only is used. So this FastCGI
server can be used on every Lemonldap::NG server even if it needs only some
parts (isolated handlers, portal,...).
2016-06-09 13:45:08 +02:00
=head1 PARAMETERS
Each parameter can be set by an option or a environment variable.
=over
2018-05-22 19:34:37 +02:00
=item --pid -p ($ENV{PID}):
2016-12-29 21:34:40 +01:00
2018-05-22 19:34:37 +02:00
pid file
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
=item --user -u ($ENV{USER}):
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
user
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
=item --group -g ($ENV{GROUP}):
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
group
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
=item --proc -n ($ENV{NPROC}):
2018-05-22 19:34:37 +02:00
Number of processus for FCGI
2016-06-09 13:45:08 +02:00
2018-05-22 19:34:37 +02:00
=item --socket -s ($ENV{SOCKET}):
Unix socket
=item --listen -l ($ENV{LISTEN}):
Listening address (HOST:PORT, :PORT, or PATH)
=item --customFunctionsFile -f ($ENV{CUSTOM_FUNCTIONS_FILE}):
file to load for custom functions
=item --engine -e ($ENV{ENGINE}):
Plack::Handler engine, default to FCGI (see below)
=item --plackOptions:
other options to pass to the Plack handler. This multi-valued parameter must
have "key=value" values.
2018-05-22 19:34:37 +02:00
See Plack::Handler::FCGI for a list of options for the default FCGI engine
2018-05-22 19:34:37 +02:00
=back
=head1 ENGINES
By default, llng-fastcgi-server uses FCGI (= L<Plack::Handler::FCGI>). Some
other engines can be used:
=head2 FCGI (default)
It uses L<FCGI::ProcManager> as manager. Other managers:
2020-04-12 20:40:24 +02:00
=over
2018-05-22 19:34:37 +02:00
=item L<FCGI::ProcManager::Dynamic>
llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -e FCGI -n 10 \
--plackOptions manager=FCGI::ProcManager::Dynamic
=back
=head2 Other FCGI::ProcManager style engines
=over
=item FCGI::Engine
=back
=head2 Event engines
=over
=item AnyEvent::FCGI
=item FCGI::Async
=item FCGI::EV
2016-06-09 13:45:08 +02:00
=back
2016-02-07 09:32:40 +01:00
=head1 SEE ALSO
L<http://lemonldap-ng.org/>
=head1 AUTHORS
=over
=item Clement Oudot, E<lt>clem.oudot@gmail.comE<gt>
=item Xavier Guimard, E<lt>x.guimard@free.frE<gt>
=back
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
2017-11-11 14:06:23 +01:00
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
2016-02-07 09:32:40 +01:00
=head1 DOWNLOAD
Lemonldap::NG is available at
2021-08-12 16:05:42 +02:00
L<https://lemonldap-ng.org/download>
2016-02-07 09:32:40 +01:00
=head1 COPYRIGHT AND LICENSE
=over
=item Copyright (C) 2008-2016 by Xavier Guimard, E<lt>x.guimard@free.frE<gt>
=item Copyright (C) 2008-2016 by Clément Oudot, E<lt>clem.oudot@gmail.comE<gt>
=back
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see L<http://www.gnu.org/licenses/>.
=cut