# parse_html_template('login_screen/user_login')
# parse_html_template('generic/error')
-BEGIN {
- use SL::System::Process;
- my $exe_dir = SL::System::Process::exe_dir;
-
- unshift @INC, "${exe_dir}/modules/override"; # Use our own versions of various modules (e.g. YAML).
- push @INC, "${exe_dir}/modules/fallback"; # Only use our own versions of modules if there's no system version.
- unshift @INC, $exe_dir;
-}
-
use Carp;
use CGI qw( -no_xhtml);
use Config::Std;
use DateTime;
use Encode;
use English qw(-no_match_vars);
+use FCGI;
use File::Basename;
+use IO::File;
use List::MoreUtils qw(all);
use List::Util qw(first);
-use POSIX;
use SL::ArchiveZipFixes;
use SL::Auth;
use SL::Dispatcher::AuthHandler;
use SL::Helper::DateTime;
use SL::InstanceConfiguration;
use SL::Template::Plugin::HTMLFixes;
+use SL::User;
+
+use Rose::Object::MakeMethods::Generic (
+ scalar => [ qw(restart_after_request) ],
+);
# Trailing new line is added so that Perl will not add the line
# number 'die' was called in.
die "cannot find locale for user " . $params{login} unless $::locale = Locale->new($::myconfig{countrycode});
$::form->{login} = $params{login}; # normaly implicit at login
-
- $::instance_conf->init;
}
}
print $::form->parse_html_template($template, \%params);
$::lxdebug->leave_sub;
- ::end_of_request();
+ end_request();
}
sub pre_startup_setup {
$::lxdebug = LXDebug->new;
$::auth = SL::Auth->new;
$::form = undef;
- %::myconfig = ();
$::request = undef;
+ %::myconfig = User->get_default_myconfig;
}
$SIG{__WARN__} = sub {
"SL::Controller::$_[0]"->new->_run_action($_[1]);
}
+sub handle_all_requests {
+ my ($self) = @_;
+
+ my $request = FCGI::Request();
+ while ($request->Accept() >= 0) {
+ $self->handle_request($request);
+
+ $self->restart_after_request(1) if $self->_interface_is_fcgi && $self->_memory_usage_is_too_high;
+ $request->LastCall if $self->restart_after_request;
+ }
+
+ exec $0 if $self->restart_after_request;
+}
+
sub handle_request {
my $self = shift;
$self->{request} = shift;
action => $action,
);
- ::end_of_request() unless $auth_result{auth_ok};
+ $self->end_request unless $auth_result{auth_ok};
delete @{ $::form }{ grep { m/^\{AUTH\}/ } keys %{ $::form } } unless $auth_result{keep_auth_vars};
$::form->footer;
+ if ($self->_interface_is_fcgi) {
+ # fcgi? send send reponse on its way before cleanup.
+ $self->{request}->Flush;
+ $self->{request}->Finish;
+ }
+
+ $::lxdebug->end_request(routing_type => $routing_type, script_name => $script_name, action => $action);
+
# cleanup
$::auth->save_session;
$::auth->expire_sessions;
$::locale = undef;
$::form = undef;
- $::myconfig = ();
+ %::myconfig = ();
$::request = undef;
- Form::disconnect_standard_dbh;
- $::lxdebug->end_request;
+ SL::DBConnect::Cache->reset_all;
$self->_watch_for_changed_files;
$action .= '&error=' . $params{error} if $params{error};
print $::request->cgi->redirect("controller.pl?action=${action}");
- ::end_of_request();
+ $self->end_request;
}
sub unrequire_bin_mozilla {
my $ok = all { (stat($_))[9] == $fcgi_file_cache{$_} } keys %fcgi_file_cache;
return if $ok;
$::lxdebug->message(LXDebug::DEBUG1(), "Program modifications detected. Restarting.");
- exit;
+ $self->restart_after_request(1);
}
sub get_standard_filehandles {
$::form->header;
print $::form->parse_html_template('login_screen/old_configuration_files', { FILES => \@old_files });
- ::end_of_request();
+ end_request();
}
-package main;
+sub _parse_number_with_unit {
+ my ($number) = @_;
-use strict;
+ return undef unless defined $number;
+ return $number unless $number =~ m{^ \s* (\d+) \s* ([kmg])b \s* $}xi;
+
+ my %factors = (K => 1024, M => 1024 * 1024, G => 1024 * 1024 * 1024);
+
+ return $1 * $factors{uc $2};
+}
+
+sub _memory_usage_is_too_high {
+ return undef unless $::lx_office_conf{system};
+
+ my %limits = (
+ rss => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_rss}),
+ size => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_vsz}),
+ );
+
+ # $::lxdebug->dump(0, "limits", \%limits);
+
+ return undef unless $limits{rss} || $limits{vsz};
+
+ my %usage;
+
+ my $in = IO::File->new("/proc/$$/status", "r") or return undef;
+
+ while (<$in>) {
+ chomp;
+ $usage{lc $1} = _parse_number_with_unit($2) if m{^ vm(rss|size): \s* (\d+ \s* [kmg]b) \s* $}ix;
+ }
+
+ $in->close;
+
+ # $::lxdebug->dump(0, "usage", \%usage);
+
+ foreach my $type (keys %limits) {
+ next if !$limits{$type};
+ next if $limits{$type} >= ($usage{$type} // 0);
+
+ $::lxdebug->message(LXDebug::WARN(), "Exiting due to memory size limit reached for type '${type}': limit " . $limits{$type} . " bytes, usage " . $usage{$type} . " bytes");
+
+ return 1;
+ }
+
+ return 0;
+}
-sub end_of_request {
+sub end_request {
die SL::Dispatcher->END_OF_REQUEST;
}