An Elixir toolkit for the AT Protocol. hexdocs.pm/atex
elixir bluesky atproto decentralization
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: split out `Atex.IdentityResolver.Handle.query_dns/2`

+87 -12
+1 -12
lib/atex/identity_resolver/handle.ex
··· 45 45 46 46 @spec resolve_via_dns(String.t()) :: {:ok, String.t()} | :error 47 47 defp resolve_via_dns(handle) do 48 - with ["did=" <> did] <- query_dns("_atproto.#{handle}", :txt), 48 + with ["did=" <> did] <- Atex.Util.query_dns("_atproto.#{handle}", :txt), 49 49 "did:" <> _ <- did do 50 50 {:ok, did} 51 51 else ··· 59 59 {:ok, %{body: "did:" <> _ = did}} -> {:ok, did} 60 60 _ -> :error 61 61 end 62 - end 63 - 64 - @spec query_dns(String.t(), :inet_res.dns_rr_type()) :: list(String.t() | list(String.t())) 65 - defp query_dns(domain, type) do 66 - domain 67 - |> String.to_charlist() 68 - |> :inet_res.lookup(:in, type) 69 - |> Enum.map(fn 70 - [result] -> to_string(result) 71 - result -> result 72 - end) 73 62 end 74 63 end
+86
lib/atex/util.ex
··· 1 + defmodule Atex.Util do 2 + # IDK why I can't use `:inet.dns_rr_type()`, I get a warning it doesn't exist, but it does. 3 + @type dns_type() :: 4 + :a 5 + | :aaaa 6 + | :caa 7 + | :cname 8 + | :gid 9 + | :hinfo 10 + | :ns 11 + | :mb 12 + | :md 13 + | :mg 14 + | :mf 15 + | :minfo 16 + | :mx 17 + | :naptr 18 + | :null 19 + | :ptr 20 + | :soa 21 + | :spf 22 + | :srv 23 + | :txt 24 + | :uid 25 + | :uinfo 26 + | :unspec 27 + | :uri 28 + | :wks 29 + 30 + defguardp is_ipv4(a, b, c, d) 31 + when is_integer(a) and is_integer(b) and is_integer(c) and is_integer(d) 32 + 33 + defguardp is_ipv4(value) 34 + when is_tuple(value) and tuple_size(value) == 4 and 35 + is_ipv4(elem(value, 0), elem(value, 1), elem(value, 2), elem(value, 3)) 36 + 37 + defguardp is_ipv6(a, b, c, d, e, f, g, h) 38 + when is_integer(a) and is_integer(b) and is_integer(c) and is_integer(d) and 39 + is_integer(e) and is_integer(f) and is_integer(g) and is_integer(h) 40 + 41 + defguardp is_ipv6(value) 42 + when is_tuple(value) and tuple_size(value) == 8 and 43 + is_ipv6( 44 + elem(value, 0), 45 + elem(value, 1), 46 + elem(value, 2), 47 + elem(value, 3), 48 + elem(value, 4), 49 + elem(value, 5), 50 + elem(value, 6), 51 + elem(value, 7) 52 + ) 53 + 54 + @spec query_dns(String.t(), dns_type()) :: 55 + list(String.t() | {priority :: integer(), String.t()}) 56 + def query_dns(domain, type) do 57 + domain 58 + |> String.to_charlist() 59 + |> :inet_res.lookup(:in, type) 60 + |> Enum.map(fn 61 + [result] -> 62 + to_string(result) 63 + 64 + value when is_ipv4(value) -> 65 + format_ipv4(value) 66 + 67 + value when is_ipv6(value) -> 68 + format_ipv6(value) 69 + 70 + {prio, dns_name} when is_integer(prio) -> 71 + {prio, to_string(dns_name)} 72 + 73 + result when is_binary(result) -> 74 + result 75 + end) 76 + end 77 + 78 + defp format_ipv4({a, b, c, d}) when is_ipv4(a, b, c, d), do: "#{a}.#{b}.#{c}.#{d}" 79 + 80 + defp format_ipv6({a, b, c, d, e, f, g, h}) when is_ipv6(a, b, c, d, e, f, g, h) do 81 + [a, b, c, d, e, f, g, h] 82 + |> Enum.map(&Integer.to_string(&1, 16)) 83 + |> Enum.join(":") 84 + |> String.downcase() 85 + end 86 + end