You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
8.0 KiB
329 lines
8.0 KiB
#!/usr/bin/perl
|
|
|
|
use Plack::Runner;
|
|
use strict;
|
|
use warnings;
|
|
use POSIX;
|
|
use Getopt::Long;
|
|
use Lemonldap::NG::Handler::Main::Reload;
|
|
|
|
our $VERSION = '2.0.0';
|
|
|
|
our (
|
|
$foreground, $engine, $nproc, $pidFile,
|
|
$socket, $user, $listen, $group,
|
|
$customFunctionsFile, %plackOptions
|
|
);
|
|
my %_apps;
|
|
|
|
$SIG{'PIPE'} = 'IGNORE';
|
|
$ENV{LLNG_DEFAULTLOGGER} ||= 'Lemonldap::NG::Common::Logger::Syslog';
|
|
|
|
$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;
|
|
$user ||= $ENV{USER};
|
|
$group ||= $ENV{GROUP};
|
|
$customFunctionsFile ||= $ENV{CUSTOM_FUNCTIONS_FILE};
|
|
|
|
#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,
|
|
'user|u=s' => \$user,
|
|
'group|g=s' => \$group,
|
|
'customFunctionsFile|f=s' => \$customFunctionsFile,
|
|
'plackOptions=s' => \%plackOptions,
|
|
);
|
|
|
|
if ($group) {
|
|
my $grp = getgrnam($group) or die "Can't change uid to $group";
|
|
POSIX::setgid($grp) or die "setgid: $!";
|
|
}
|
|
|
|
if ($user) {
|
|
my $uid = getpwnam($user) or die "Can't change uid to $user";
|
|
POSIX::setuid($uid) or die "setuid: $!";
|
|
}
|
|
|
|
unless ($>) {
|
|
die "Refuse to run as root. Aborting";
|
|
}
|
|
|
|
if ($customFunctionsFile) {
|
|
eval { require $customFunctionsFile };
|
|
die $@ if ($@);
|
|
}
|
|
|
|
my %builder = (
|
|
reload => sub {
|
|
return Lemonldap::NG::Handler::Server::Nginx->reload();
|
|
},
|
|
status => sub {
|
|
return Lemonldap::NG::Handler::Server::Nginx->status();
|
|
},
|
|
manager => sub {
|
|
require Lemonldap::NG::Manager;
|
|
return Lemonldap::NG::Manager->run( {} );
|
|
},
|
|
cgi => sub {
|
|
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}->(@_);
|
|
};
|
|
},
|
|
psgi => sub {
|
|
return sub {
|
|
my $script = $_[0]->{SCRIPT_FILENAME};
|
|
return $_apps{$script}->(@_) if ( $_apps{$script} );
|
|
$_apps{$script} = do $script;
|
|
unless ( $_apps{$script} and ref $_apps{$script} ) {
|
|
die "Unable to load $_[0]->{SCRIPT_FILENAME}";
|
|
}
|
|
return $_apps{$script}->(@_);
|
|
}
|
|
},
|
|
);
|
|
|
|
require Lemonldap::NG::Handler::Server::Nginx;
|
|
$_apps{handler} = Lemonldap::NG::Handler::Server::Nginx->run( {} );
|
|
|
|
my $app = sub {
|
|
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
|
|
Lemonldap::NG::Handler::Main->onReload(
|
|
bless( {}, 'Lemonldap::NG::Handler::FastCGI::Loader' ),
|
|
'loadCustomHandlers' );
|
|
|
|
my $server = Plack::Runner->new();
|
|
$server->parse_options(
|
|
'-s' => $engine,
|
|
'-E' => 'deployment',
|
|
'--pid' => $pidFile,
|
|
'--nproc' => $nproc,
|
|
'--socket' => $socket,
|
|
( $listen ? ( '--listen', $listen ) : () ),
|
|
'--proc-title' => 'llng-fastcgi-server',
|
|
( $foreground ? () : '--daemonize' ),
|
|
'--no-default-middleware',
|
|
%plackOptions,
|
|
);
|
|
|
|
$server->run($app);
|
|
|
|
package Lemonldap::NG::Handler::FastCGI::Loader;
|
|
|
|
# Load configuration and look if custom handlers have been defined
|
|
sub loadCustomHandlers {
|
|
my ( $obj, $conf ) = @_;
|
|
foreach my $lltype ( keys %{ $conf->{nginxCustomHandlers} || {} } ) {
|
|
my $v = $conf->{nginxCustomHandlers}->{$lltype};
|
|
if ( $v =~ m#[/\\\.]# ) {
|
|
eval { require $v; };
|
|
}
|
|
else {
|
|
eval "use $v";
|
|
}
|
|
if ($@) {
|
|
print STDERR "Unable to load $v, skipping: $@\n";
|
|
next;
|
|
}
|
|
$builder{$lltype} = sub {
|
|
require $v;
|
|
return $v->run( {} );
|
|
};
|
|
}
|
|
return 1;
|
|
}
|
|
__END__
|
|
|
|
=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,...).
|
|
|
|
=head1 PARAMETERS
|
|
|
|
Each parameter can be set by an option or a environment variable.
|
|
|
|
=over
|
|
|
|
=item --pid -p ($ENV{PID}):
|
|
|
|
pid file
|
|
|
|
=item --user -u ($ENV{USER}):
|
|
|
|
user
|
|
|
|
=item --group -g ($ENV{GROUP}):
|
|
|
|
group
|
|
|
|
=item --proc -n ($ENV{NPROC}):
|
|
|
|
Number of processus for FCGI
|
|
|
|
=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 Plack. This multi-valued parameter must have
|
|
"key=value" values.
|
|
|
|
Example to use L<FCGI::ProcManager::Constrained> instead of default FCGI manager
|
|
(L<FCGI::ProcManager>):
|
|
|
|
llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -e FCGI -n 10 \
|
|
--plackOptions manager=FCGI::ProcManager::Constrained
|
|
|
|
=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:
|
|
|
|
=over
|
|
|
|
=item L<FCGI::ProcManager::Constrained>
|
|
|
|
Example to launch it:
|
|
|
|
llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -e FCGI -n 10 \
|
|
--plackOptions manager=FCGI::ProcManager::Constrained
|
|
|
|
You can then set environment values (in /etc/default/llng-fastcgi-server file
|
|
for example):
|
|
|
|
PM_MAX_REQUESTS=10000
|
|
PM_SIZECHECK_NUM_REQUESTS=100
|
|
PM_MAX_SIZE=300000
|
|
|
|
=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
|
|
|
|
=back
|
|
|
|
=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:
|
|
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
|
|
|
|
=head1 DOWNLOAD
|
|
|
|
Lemonldap::NG is available at
|
|
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
|
|
|
|
=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
|
|
|