lean4-htt/tests/lean/run/async_dns.lean
Sofia Rodrigues fe1b407031
feat: add DNS resolution functions to the standard library (#8072)
This PR adds DNS functions to the standard library

---------

Co-authored-by: Henrik Böving <hargonix@gmail.com>
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
2025-06-27 11:11:47 +00:00

67 lines
2.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Std.Internal.Async
import Std.Internal.UV
import Std.Net.Addr
open Std.Internal.IO Async
open Std.Net
open Std.Net
def assertBEq [BEq α] [ToString α] (actual expected : α) : IO Unit := do
unless actual == expected do
throw <| IO.userError <|
s!"expected '{expected}', got '{actual}'"
def baseSelector (asyncWaiter : AsyncTask α) : Selector α :=
{
tryFn := do
if ← IO.hasFinished asyncWaiter then
let result ← IO.ofExcept asyncWaiter.get
return some result
else
return none
registerFn waiter := do
discard <| AsyncTask.mapIO (x := asyncWaiter) fun data => do
let lose := return ()
let win promise := promise.resolve (.ok data)
waiter.race lose win
unregisterFn := pure ()
}
def race (a : AsyncTask α) (b : AsyncTask β) (map : Except α β → AsyncTask γ) : IO (AsyncTask γ) := do
Selectable.one #[
.case (baseSelector a) fun a => return map (.error a),
.case (baseSelector b) fun b => return map (.ok b),
]
def timeout (a : AsyncTask α) (time : Std.Time.Millisecond.Offset) : IO (AsyncTask α) := do
race (← sleep time) a fun
| .ok res => Task.pure (.ok res)
| .error _ => Task.pure (.error (IO.userError "Timeout."))
def runDNS : Async Unit := do
let infos ← await <| (← timeout (← DNS.getAddrInfo "google.com" "http") 10000)
unless infos.size > 0 do
(throw <| IO.userError <| "No DNS results for google.com" : IO _)
def runDNSNoAscii : Async Unit := do
let infos ← await <| (← timeout (← DNS.getAddrInfo "google.com▸" "http") 10000)
unless infos.size > 0 do
(throw <| IO.userError <| "No DNS results for google.com" : IO _)
def runReverseDNS : Async Unit := do
let result ← await (← DNS.getNameInfo (.v4 ⟨.ofParts 8 8 8 8, 53⟩))
assertBEq result.service "domain"
assertBEq result.host "dns.google"
#eval runDNS.toIO >>= AsyncTask.block
/--
error: invalid argument (error code: 22, invalid argument)
file: name is not ASCII.
-/
#guard_msgs in #eval runDNSNoAscii.toIO >>= AsyncTask.block
#eval runReverseDNS.toIO >>= AsyncTask.block