Packages
erldns
10.4.4
11.1.0
11.0.3
11.0.2
11.0.1
11.0.0
10.6.0
10.5.6
10.5.5
10.5.4
10.5.3
10.5.2
10.5.1
10.5.0
10.4.4
10.4.3
10.4.2
10.4.1
10.4.0
10.3.0
10.2.1
10.2.0
10.1.0
10.0.0
10.0.0-rc4
10.0.0-rc3
10.0.0-rc2
10.0.0-rc1
9.1.0
9.0.0
9.0.0-rc3
9.0.0-rc2
9.0.0-rc1
8.1.0
8.0.0
8.0.0-rc6
8.0.0-rc5
8.0.0-rc4
8.0.0-rc3
8.0.0-rc2
8.0.0-rc1
7.0.0
7.0.0-rc9
7.0.0-rc8
7.0.0-rc7
7.0.0-rc6
7.0.0-rc5
7.0.0-rc4
7.0.0-rc3
7.0.0-rc2
7.0.0-rc12
7.0.0-rc11
7.0.0-rc10
7.0.0-rc1
6.0.2
6.0.1
6.0.0
5.0.0
4.3.1
4.3.0
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.2
4.1.1
4.1.0
4.0.0
3.0.0
1.0.0
Erlang Authoritative DNS Server
Current section
Files
Jump to
Current section
Files
src/zones/erldns_zone_encoder.erl
-module(erldns_zone_encoder).
-moduledoc false.
-include_lib("dns_erlang/include/dns.hrl").
-include_lib("kernel/include/logger.hrl").
-include_lib("erldns/include/erldns.hrl").
-define(LOG_METADATA, #{domain => [erldns, zones, encoder]}).
-export([encode/3]).
-spec encode(erldns:zone(), #{atom() => dynamic()}, [erldns_zone_codec:encoder()]) ->
not_implemented | json:encode_value().
encode(Zone, #{mode := zone_records_to_json}, Encoders) ->
encode_zone_records_to_json(Zone, Encoders);
encode(Zone, #{mode := {zone_records_to_json, RecordName}}, Encoders) ->
encode_zone_records_to_json(Zone, RecordName, Encoders);
encode(Zone, #{mode := {zone_records_to_json, RecordName, RecordType}}, Encoders) ->
encode_zone_records_to_json(Zone, RecordName, RecordType, Encoders);
encode(Zone, #{mode := zone_meta_to_json}, _) ->
zone_meta_to_json(Zone, #{});
encode(Zone, #{mode := zone_to_json}, Encoders) ->
Records = records_to_json(Zone, Encoders),
Extra = #{~"records" => Records},
zone_meta_to_json(Zone, Extra).
% Note: Private key material is purposely omitted
-spec zone_meta_to_json(erldns:zone(), dynamic()) -> json:encode_value().
zone_meta_to_json(Zone, MaybeRecords) ->
Zone0 = #{
~"name" => Zone#zone.name,
~"version" => Zone#zone.version,
~"records_count" => Zone#zone.record_count
},
ZoneJson = maps:merge(Zone0, MaybeRecords),
#{~"erldns" => #{~"zone" => ZoneJson}}.
% Internal API
encode_zone_records_to_json(Zone, Encoders) ->
Records = erldns_zone_cache:get_zone_records(Zone),
do_encode(Records, Encoders).
encode_zone_records_to_json(Zone, RecordName, Encoders) ->
Records = erldns_zone_cache:get_records_by_name(Zone, RecordName),
do_encode(Records, Encoders).
encode_zone_records_to_json(Zone, RecordName, RecordType, Encoders) ->
Type = dns_names:name_type(RecordType),
Records = erldns_zone_cache:get_records_by_name_and_type(Zone, RecordName, Type),
do_encode(Records, Encoders).
records_to_json(Zone, Encoders) ->
Records = erldns_zone_cache:get_zone_records(Zone),
do_encode(Records, Encoders).
do_encode(Records, Encoders) ->
lists:flatmap(fun(Record) -> encode_record(Record, Encoders) end, Records).
encode_record(
#dns_rr{name = Name, type = Type, ttl = Ttl, data = Data} = Record,
Encoders
) ->
Encoded = erlang:iolist_to_binary(dns_zone:encode_rdata(Type, Data)),
case Encoded of
<<"\\#", _/binary>> ->
%% dns_zone:encode_rdata/2 falls back to RFC 3597 \# length hex for unknown type
?LOG_WARNING(#{what => unable_to_encode_record, record => Record}, ?LOG_METADATA),
try_custom_encoders(Record, Encoders);
_ ->
[
#{
~"name" => erlang:iolist_to_binary(io_lib:format("~s.", [Name])),
~"type" => dns_names:type_name(Type),
~"ttl" => Ttl,
~"content" => Encoded
}
]
end.
try_custom_encoders(_, []) ->
[];
try_custom_encoders(Record, [Encoder | Rest]) ->
case Encoder(Record) of
not_implemented ->
try_custom_encoders(Record, Rest);
EncodedData ->
[EncodedData]
end.