mirror of
https://github.com/webmin/webmin.git
synced 2026-10-01 01:40:39 +01:00
Merge pull request #2858 from webmin/dev/fix-miniserv-config-cache
Fix stale miniserv configuration reads
This commit is contained in:
49
t/web-lib-funcs-miniserv-config.t
Normal file
49
t/web-lib-funcs-miniserv-config.t
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/perl
|
||||
# Concurrent WebSocket updates must not reuse a same-second config snapshot.
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use File::Temp qw(tempdir);
|
||||
use File::Basename qw(dirname);
|
||||
use File::Spec;
|
||||
|
||||
require File::Spec->rel2abs(dirname(__FILE__).'/../web-lib-funcs.pl');
|
||||
my $directory = tempdir(CLEANUP => 1);
|
||||
my $file = "$directory/miniserv.conf";
|
||||
{
|
||||
no warnings qw(redefine once);
|
||||
*main::get_miniserv_config_file = sub { return $file; };
|
||||
}
|
||||
|
||||
# replace_config(contents) simulates another process writing within one second.
|
||||
sub replace_config
|
||||
{
|
||||
my ($contents) = @_;
|
||||
open(my $fh, '>', $file) or die $!;
|
||||
print {$fh} $contents;
|
||||
close($fh) or die $!;
|
||||
utime(1700000000, 1700000000, $file) or die $!;
|
||||
}
|
||||
|
||||
replace_config("port=10000\nwebsockets_/test/ws-555=first\n");
|
||||
my %first;
|
||||
ok(main::get_miniserv_config(\%first), 'read initial configuration');
|
||||
is($first{'websockets_/test/ws-555'}, 'first', 'first route is present');
|
||||
|
||||
# Allocation must retain a route added since the caller's initial config read.
|
||||
replace_config("port=10000\nwebsockets_/test/ws-555=first\n".
|
||||
"websockets_/test/ws-556=second\n");
|
||||
my %added;
|
||||
main::get_miniserv_config(\%added);
|
||||
is($added{'websockets_/test/ws-556'}, 'second',
|
||||
'same-second route addition is visible');
|
||||
|
||||
# Cleanup must not restore a route another backend has already removed.
|
||||
replace_config("port=10000\nwebsockets_/test/ws-556=second\n");
|
||||
my %removed;
|
||||
main::get_miniserv_config(\%removed);
|
||||
ok(!exists($removed{'websockets_/test/ws-555'}),
|
||||
'same-second route removal is visible');
|
||||
is($removed{'websockets_/test/ws-556'}, 'second',
|
||||
'unrelated route survives cleanup');
|
||||
done_testing();
|
||||
@@ -3083,7 +3083,9 @@ hash reference.
|
||||
=cut
|
||||
sub get_miniserv_config
|
||||
{
|
||||
return &read_file_cached_with_stat(&get_miniserv_config_file(), $_[0]);
|
||||
# WebSocket backends can change routes several times within one second.
|
||||
# An mtime-based cache can lose another process's update even under a file lock.
|
||||
return &read_file(&get_miniserv_config_file(), $_[0]);
|
||||
}
|
||||
|
||||
=head2 put_miniserv_config(&hash)
|
||||
|
||||
Reference in New Issue
Block a user