From: Leo-Andres Hofmann Date: Sun, 8 May 2022 12:09:50 +0000 (+0200) Subject: pakfire.cgi: Implement Post/Redirect/Get pattern X-Git-Url: http://git.ipfire.org/?p=people%2Fpmueller%2Fipfire-2.x.git;a=commitdiff_plain;h=85d570843ef7b4b1a428dadf93e5a2a8410348ca pakfire.cgi: Implement Post/Redirect/Get pattern Refreshing the Pakfire page may cause a command to be executed multiple times and induce odd errors. This patch implements a HTTP 303 redirect after form processing, which causes the browser to discard the POST form data. Navigating backward or reloading the page now does not trigger multiple executions anymore. Fixes: #12781 Signed-off-by: Leo-Andres Hofmann Acked-by: Peter Müller --- diff --git a/html/cgi-bin/pakfire.cgi b/html/cgi-bin/pakfire.cgi index ec3ee2cc64..6fade81bd1 100644 --- a/html/cgi-bin/pakfire.cgi +++ b/html/cgi-bin/pakfire.cgi @@ -21,6 +21,7 @@ use strict; use List::Util qw(any); +use URI; # enable only the following on debugging purpose #use warnings; @@ -37,12 +38,17 @@ my %color = (); my %pakfiresettings = (); my %mainsettings = (); +# The page mode is used to explictly switch between user interface functions: +my $PM_DEFAULT = 'default'; # Default user interface with command processing +my $PM_LOGREAD = 'logread'; # Log messages viewer (ignores all commands) +my $pagemode = $PM_DEFAULT; + # Load general settings &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("${General::swroot}/pakfire/settings", \%pakfiresettings); &General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color); -# Get CGI request data +# Get CGI POST request data $cgiparams{'ACTION'} = ''; $cgiparams{'FORCE'} = ''; @@ -51,6 +57,17 @@ $cgiparams{'DELPAKS'} = ''; &Header::getcgihash(\%cgiparams); +# Get CGI GET request data (if available) +if($ENV{'QUERY_STRING'}) { + my $uri = URI->new($ENV{'REQUEST_URI'}); + my %query = $uri->query_form; + + my $mode = lc($query{'mode'} // ''); + if(($mode eq $PM_DEFAULT) || ($mode eq $PM_LOGREAD)) { + $pagemode = $mode; # Limit to existing modes + } +} + ### Process AJAX/JSON request ### if($cgiparams{'ACTION'} eq 'json-getstatus') { # Send HTTP headers @@ -96,19 +113,24 @@ if($cgiparams{'ACTION'} eq 'json-getstatus') { } ### Process Pakfire install/update commands ### -if($cgiparams{'ACTION'} ne '') { +if(($cgiparams{'ACTION'} ne '') && ($pagemode eq $PM_DEFAULT)) { if(&_is_pakfire_busy()) { $errormessage = $Lang::tr{'pakfire already busy'}; + $pagemode = $PM_LOGREAD; # Running Pakfire instance found, switch to log viewer mode } elsif(($cgiparams{'ACTION'} eq 'install') && ($cgiparams{'FORCE'} eq 'on')) { my @pkgs = split(/\|/, $cgiparams{'INSPAKS'}); &General::system_background("/usr/local/bin/pakfire", "install", "--non-interactive", "--no-colors", @pkgs); + &_http_pagemode_redirect($PM_LOGREAD, 1); } elsif(($cgiparams{'ACTION'} eq 'remove') && ($cgiparams{'FORCE'} eq 'on')) { my @pkgs = split(/\|/, $cgiparams{'DELPAKS'}); &General::system_background("/usr/local/bin/pakfire", "remove", "--non-interactive", "--no-colors", @pkgs); + &_http_pagemode_redirect($PM_LOGREAD, 1); } elsif($cgiparams{'ACTION'} eq 'update') { &General::system_background("/usr/local/bin/pakfire", "update", "--force", "--no-colors"); + &_http_pagemode_redirect($PM_LOGREAD, 1); } elsif($cgiparams{'ACTION'} eq 'upgrade') { &General::system_background("/usr/local/bin/pakfire", "upgrade", "-y", "--no-colors"); + &_http_pagemode_redirect($PM_LOGREAD, 1); } elsif($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { $pakfiresettings{"TREE"} = $cgiparams{"TREE"}; @@ -122,6 +144,7 @@ if($cgiparams{'ACTION'} ne '') { # Update lists &General::system_background("/usr/local/bin/pakfire", "update", "--force", "--no-colors"); + &_http_pagemode_redirect($PM_LOGREAD, 1); } } } @@ -221,8 +244,8 @@ if ($errormessage) { &Header::closebox(); } -# Show log output while Pakfire is running -if(&_is_pakfire_busy()) { +# Show only log output while Pakfire is running and stop afterwards +if(($pagemode eq $PM_LOGREAD) || (&_is_pakfire_busy())) { &Header::openbox("100%", "center", "Pakfire"); print <