Merge pull request #2836 from webmin/dev/nginx-add-return-code-redirects
Some checks are pending
Tests / prove (push) Waiting to run
Package and upload artifacts / build (push) Waiting to run

Add return code redirects to Nginx URL rewriting pages
This commit is contained in:
Jamie Cameron
2026-09-07 10:27:17 -07:00
committed by GitHub
7 changed files with 89 additions and 0 deletions

View File

@@ -5,6 +5,7 @@
* Add webserver logging controls to Usermin Configuration module
* Add option to rotate Webmin and Usermin webserver logs using `logrotate` instead of periodically clearing them [#2821](https://github.com/webmin/webmin/pull/2821)
* Add DNF 4 and 5 package hold management to the Software Package Updates module
* Add `return` based redirects with 301, 302, 303, 307 and 308 codes to the URL Re-Writing pages in the Nginx Webserver module [forum.virtualmin.com/t/137940](https://forum.virtualmin.com/t/137940)
* Fix DNF update confirmations by previewing packages and dependencies that will be installed or updated
* Fix PostgreSQL initialization on EL systems to use SCRAM-SHA-256 authentication by default
* Fix IPsec host key generation with modern Libreswan [#2132](https://github.com/webmin/webmin/issues/2132)

View File

@@ -23,6 +23,8 @@ print &ui_table_start($text{'rewrite_header'}, undef, 2);
print &nginx_rewrite_input("rewrite", $location);
print &nginx_return_input("return", $location);
print &nginx_onoff_input("rewrite_log", $location);
print &ui_table_end();

View File

@@ -19,6 +19,8 @@ print &ui_table_start($text{'rewrite_header'}, undef, 2);
print &nginx_rewrite_input("rewrite", $server);
print &nginx_return_input("return", $server);
print &nginx_onoff_input("rewrite_log", $server);
print &ui_table_end();

View File

@@ -324,6 +324,17 @@ rewrite_redirect=Return 302 redirect
rewrite_permanent=Return 301 redirect
rewrite_efrom=Source path $1 contains spaces
rewrite_eto=Destination URL $1 is missing or contains spaces
opt_return=Redirect all requests
rewrite_return_none=No redirect
rewrite_return_to=to
rewrite_return_eg=/uri or https://example.com$request_uri
rewrite_return_301=301 (Moved permanently)
rewrite_return_302=302 (Found)
rewrite_return_303=303 (See other)
rewrite_return_307=307 (Temporary redirect)
rewrite_return_308=308 (Permanent redirect)
rewrite_ereturn=Redirect URL is missing or contains spaces
rewrite_ereturncode=Invalid redirect HTTP code
location_create=Create Location
location_edit=Edit Location

View File

@@ -1462,6 +1462,75 @@ for(my $i=0; defined(my $from = $in->{$name."_from_".$i}); $i++) {
&save_directive($parent, $name, \@obj);
}
# list_return_redirect_codes()
# Returns the HTTP codes that the return directive accepts with a URL
sub list_return_redirect_codes
{
return ( 301, 302, 303, 307, 308 );
}
# get_return_redirect(&object)
# Returns the code and URL of a return directive if it is a redirect, or an
# empty list for other uses such as return 404
sub get_return_redirect
{
my ($obj) = @_;
my @w = @{$obj->{'words'}};
if (@w == 2 && &indexof($w[0], &list_return_redirect_codes()) >= 0) {
return @w;
}
elsif (@w == 1 && $w[0] =~ /^(https?:\/\/|\$scheme)/) {
# Single URL form defaults to a 302 redirect
return ( 302, $w[0] );
}
return ( );
}
# nginx_return_input(name, &parent)
# Returns HTML for a redirect via the return directive
sub nginx_return_input
{
my ($name, $parent) = @_;
return undef if (!&supported_directive($name, $parent));
my $obj = &find($name, $parent);
my ($code, $url) = $obj ? &get_return_redirect($obj) : ( );
# Leave a return directive that is not a redirect alone
return undef if ($obj && !$code);
my $sel = &ui_select($name."_code", $code || 301,
[ map { [ $_, $text{'rewrite_return_'.$_} ] }
&list_return_redirect_codes() ]);
return &ui_table_row($text{'opt_'.$name},
&ui_opt_textbox($name, $url, 50, $text{'rewrite_return_none'},
$sel." ".$text{'rewrite_return_to'}." ", 0,
[ $name."_code" ], undef,
"placeholder=\"".
&quote_escape($text{'rewrite_return_eg'})."\""), 3);
}
# nginx_return_parse(name, &parent, &in)
# Updates the config with input from nginx_return_input
sub nginx_return_parse
{
my ($name, $parent, $in) = @_;
return undef if (!&supported_directive($name, $parent));
$in ||= \%in;
my $obj = &find($name, $parent);
# Never touch a return directive that was not shown in the form
return undef if ($obj && !&get_return_redirect($obj));
if ($in->{$name."_def"}) {
&save_directive($parent, $name, [ ]);
}
else {
my $code = $in->{$name."_code"};
&indexof($code, &list_return_redirect_codes()) >= 0 ||
&error($text{'rewrite_ereturncode'});
my $url = $in->{$name};
$url =~ /^\S+$/ || &error($text{'rewrite_ereturn'});
&save_directive($parent, $name, [ { 'name' => $name,
'words' => [ $code, $url ] } ]);
}
}
# list_log_formats([&server])
# Returns a list of all log format names
sub list_log_formats

View File

@@ -16,6 +16,8 @@ $location || &error($text{'location_egone'});
&nginx_rewrite_parse("rewrite", $location);
&nginx_return_parse("return", $location);
&nginx_onoff_parse("rewrite_log", $location);
&flush_config_file_lines();

View File

@@ -14,6 +14,8 @@ $server || &error($text{'server_egone'});
&nginx_rewrite_parse("rewrite", $server);
&nginx_return_parse("return", $server);
&nginx_onoff_parse("rewrite_log", $server);
&flush_config_file_lines();