jiahuili430 commented on code in PR #5983: URL: https://github.com/apache/couchdb/pull/5983#discussion_r3155499937
########## src/couch_replicator/src/couch_replicator_dns.erl: ########## @@ -0,0 +1,94 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_replicator_dns). + +-export([ + resolve_host/1, + parse_config/1, + match_pattern/2, + get_overrides/0 +]). + +-type dns_override() :: {binary(), binary()}. + +-spec resolve_host(string()) -> {string(), string() | undefined}. +resolve_host(Host) -> + case find_override(unicode:characters_to_binary(Host), get_overrides()) of + {ok, Target} -> + {binary_to_list(Target), Host}; + not_found -> + {Host, undefined} + end. + +-spec get_overrides() -> [dns_override()]. +get_overrides() -> + case config:get("replicator", "dns_overrides", undefined) of + undefined -> + []; + ConfigStr -> + parse_config(ConfigStr) + end. + +-spec parse_config(string()) -> [dns_override()]. +parse_config(ConfigStr) -> + Entries = binary:split( + unicode:characters_to_binary(ConfigStr), <<",">>, [global, trim] + ), + lists:filtermap(fun parse_entry/1, Entries). + +parse_entry(<<>>) -> + false; +parse_entry(Entry0) -> + Entry = string:trim(Entry0), + case binary:split(Entry, <<":">>) of + [Pattern0, Target0] -> + Pattern = string:trim(Pattern0), + Target = string:trim(Target0), + case {Pattern, Target} of + {<<>>, _} -> invalid_entry(Entry); + {_, <<>>} -> invalid_entry(Entry); + _ -> {true, {Pattern, Target}} + end; + _ -> + invalid_entry(Entry) + end. + +invalid_entry(Entry) -> + couch_log:warning("Invalid dns_override entry: ~ts", [Entry]), + false. + +find_override(_Host, []) -> + not_found; +find_override(Host, [{Pattern, Target} | Rest]) -> + case match_pattern(Host, Pattern) of + true -> + {ok, Target}; + false -> + find_override(Host, Rest) + end. + +-spec match_pattern(binary() | string(), binary() | string()) -> boolean(). +match_pattern(Host0, Pattern0) -> + Host = unicode:characters_to_binary(Host0), + Pattern = unicode:characters_to_binary(Pattern0), + match_pattern_binary(Host, Pattern). + +match_pattern_binary(Host, <<"*", Suffix/binary>>) -> + % wildcard match: extract last N bytes from Host and compare to Suffix + % size check prevents binary:part crash when Host is shorter than Suffix + HostSize = byte_size(Host), + SuffixSize = byte_size(Suffix), + HostSize >= SuffixSize andalso + binary:part(Host, HostSize - SuffixSize, SuffixSize) =:= Suffix; Review Comment: > -spec part(Subject, Pos, Len) -> [binary](https://www.erlang.org/doc/apps/erts/erlang.html#t:binary/0)() when Subject :: [binary](https://www.erlang.org/doc/apps/erts/erlang.html#t:binary/0)(), Pos :: [non_neg_integer](https://www.erlang.org/doc/apps/erts/erlang.html#t:non_neg_integer/0)(), Len :: [integer](https://www.erlang.org/doc/apps/erts/erlang.html#t:integer/0)(). https://www.erlang.org/doc/apps/stdlib/binary.html#part/3 `HostSize - SuffixSize` must be a non_neg_integer, should we validate that first? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
