fix(erlang): pass expected version to worker and fail fast on xdb mismatch

This commit is contained in:
Alice39s 2026-06-28 05:17:59 +09:00
parent e50ead2cba
commit daf6749c34
No known key found for this signature in database
GPG Key ID: 0E0AA11C3939DDDD
3 changed files with 24 additions and 27 deletions

View File

@ -67,12 +67,12 @@ pool_child_specs() ->
Acc
end, [], DbConfig).
make_pool_spec(PoolName, _Version, File, PoolArgsCfg) ->
make_pool_spec(PoolName, Version, File, PoolArgsCfg) ->
PoolArgs = [
{strategy, fifo},
{name, {local, PoolName}},
{worker_module, ip2region_worker}
| PoolArgsCfg
],
WorkerArgs = [{xdb_file, File}],
WorkerArgs = [{xdb_file, File}, {expected_version, Version}],
poolboy:child_spec(PoolName, PoolArgs, WorkerArgs).

View File

@ -62,10 +62,14 @@ init(Args) ->
{ok, IoDevice} = file:open(XdbFileName, [read, binary]),
{ok, HeaderBin} = file:read(IoDevice, ?XDB_HEADER_SIZE),
{ok, Header} = ip2region_xdb:parse_header(HeaderBin),
ExpectedVersion = proplists:get_value(expected_version, Args),
case resolve_version(Header) of
{ok, Version} ->
{ok, Version} when ExpectedVersion =:= undefined; ExpectedVersion =:= Version ->
load_vector_index(IoDevice, Version),
{ok, #state{xdb_fd = IoDevice, version = Version}};
{ok, Version} ->
file:close(IoDevice),
{stop, {xdb_version_mismatch, ExpectedVersion, Version}};
{error, Reason} ->
file:close(IoDevice),
{stop, Reason}

View File

@ -5,7 +5,7 @@
-define(IPV6_RESULT, "United States|Florida|Miami|Google LLC|US").
search_test_() ->
{ok, _} = application:ensure_all_started(ip2region),
{ok, _} = ip2region_test_util:start_app(),
A = "中国|广东省|广州市|中国电信|CN",
Region0 = xdb:search("1.0.8.0"),
Region1 = xdb:search(<<"1.0.8.0">>),
@ -19,7 +19,7 @@ search_test_() ->
].
ipv6_search_test_() ->
setup_ipv6(),
{ok, _} = ip2region_test_util:start_app(),
[
?_assert(?IPV6_RESULT =:= xdb:search("2001:4860:4860::8888")),
?_assert(?IPV6_RESULT =:= xdb:search(<<"2001:4860:4860::8888">>)),
@ -27,7 +27,7 @@ ipv6_search_test_() ->
].
invalid_search_test_() ->
{ok, _} = application:ensure_all_started(ip2region),
{ok, _} = ip2region_test_util:start_app(),
[
?_assertEqual({error, bad_ip_format}, xdb:search("xxx.0.8.0")),
?_assertEqual({error, bad_ip_format}, xdb:search("::ggg")),
@ -35,27 +35,20 @@ invalid_search_test_() ->
].
ipv6_pool_not_configured_test() ->
try application:stop(ip2region) catch _:_ -> ok end,
try application:unload(ip2region) catch _:_ -> ok end,
ok = application:load(ip2region),
ok = application:set_env(ip2region, db, [{ipv4, "ip2region.xdb"}]),
{ok, _} = application:ensure_all_started(ip2region),
{ok, _} = ip2region_test_util:start_app([{ipv4, "ip2region.xdb"}]),
?assertEqual({error, pool_not_configured}, xdb:search("2001:4860:4860::8888")).
setup_ipv6() ->
try application:stop(ip2region) catch _:_ -> ok end,
try application:unload(ip2region) catch _:_ -> ok end,
ok = application:load(ip2region),
RepoRoot = repo_root(),
V6File = filename:join([RepoRoot, "data", "ip2region_v6.xdb"]),
ok = application:set_env(ip2region, db, [
{ipv4, "ip2region.xdb"},
{ipv6, V6File}
xdb_version_mismatch_test() ->
{ok, _} = ip2region_test_util:start_app(),
V4File = filename:join([
ip2region_test_util:repo_root(), "binding", "erlang", "priv", "ip2region.xdb"
]),
{ok, _} = application:ensure_all_started(ip2region).
repo_root() ->
TestDir = filename:dirname(?FILE),
ErlangDir = filename:dirname(TestDir),
BindingDir = filename:dirname(ErlangDir),
filename:dirname(BindingDir).
error_logger:tty(false),
try
?assertEqual(
{error, {xdb_version_mismatch, ipv6, ipv4}},
ip2region_worker:start([{xdb_file, V4File}, {expected_version, ipv6}])
)
after
error_logger:tty(true)
end.