Expand description
Domain WHOIS and RDAP lookups, with availability detection you can audit.
use monovm_whois::WhoisClient;
let client = WhoisClient::new()?;
let lookup = client.lookup("example.com")?;
println!("{} is {}", lookup.domain, lookup.availability());
if let Some(record) = &lookup.record {
println!("registrar: {:?}", record.registrar);
println!("expires: {:?}", record.expires);
}§The problem this crate is about
WHOIS has no status codes. A registry answering “that domain is free”, one answering “you are querying too fast”, and one answering “I do not serve that suffix” all send prose over the same socket, and every one of them can contain the word available. Libraries in this space overwhelmingly resolve that ambiguity the same way — anything that is not recognisably a record is treated as availability — which means a rate-limited registry reports its entire zone as free to register.
This crate never does that. A response that cannot be interpreted produces
Error::Inconclusive, a refusal produces Error::Refused, and neither is
ever an Availability. There is deliberately no Availability::Unknown,
because an uncertain answer that renders as “available” is the one outcome a
caller must not be handed.
§How it is put together
Six layers, each with one job and no knowledge of the others:
| Layer | Responsibility | Key abstraction |
|---|---|---|
domain | Validated values — a name, a suffix, a verdict | DomainName, Tld |
registry | Which registry serves a suffix, and how to reach it | RegistryProvider |
transport | Talking to servers. The only I/O in the crate | Transport |
cache | Not asking twice | ResponseCache |
detect | Deciding what a response said | AvailabilityRule |
parser | Turning a record into data | RecordParser |
client composes them. Every layer is a trait with a bundled implementation,
so a caller can replace any one of them — a private registry list, a transport
over a proxy, a Redis cache, an extra detection rule for a registry that words
things unusually — without forking the crate.
§What you get
- Coverage. 872 curated suffixes plus IANA’s RDAP bootstrap registry, for over 1600 in total.
- RDAP. A full RFC 9083 client and typed model, used as a fallback when port
43 refuses and preferred when
Preference::Rdapis set. RDAP’s 404 makes availability a fact rather than an inference. - Structured records.
WhoisRecordwith typed dates, statuses, name servers and contacts, instead of the server’s raw text. - Referral chasing. Thin registries answer with a pointer to the registrar; following it is the difference between knowing a domain is taken and knowing who holds it.
- Auditable verdicts. Every answer names the rule that produced it and why,
and
WhoisClient::explainshows what every rule thought. - Rate limiting, retries and caching, composed as transport decorators.
- Both runtimes.
WhoisClientandAsyncWhoisClient.
§Features
| Feature | Default | Gives you |
|---|---|---|
blocking | yes | WhoisClient and the synchronous transports |
rdap | yes | RDAP over HTTPS, and the typed rdap model |
parser | yes | WhoisRecord and record parsing |
async | no | AsyncWhoisClient and the Tokio transports |
iana-bootstrap | no | Refreshing the RDAP registry from IANA at runtime |
cli | no | The monovm-whois command line tool |
mock | no | MockTransport, for your own tests |
§A note on what a verdict means
Availability detection over WHOIS is inference, and this crate is explicit about
how much. Every Verdict carries a
Confidence: Definitive for a structured RDAP answer,
High for wording curated for that specific registry, Medium for a pattern
that generalises, Low for the one inference drawn from absence of evidence. A
caller who needs certainty can require Definitive and use
Preference::RdapOnly.
Re-exports§
pub use domain::Availability;pub use domain::DomainName;pub use domain::SuffixSplit;pub use domain::Tld;pub use error::DomainError;pub use error::Error;pub use error::Refusal;pub use error::Result;pub use client::Explanation;pub use client::Lookup;pub use client::Preference;pub use client::ReferralPolicy;pub use client::CheckReport;asyncorblockingpub use client::Checker;blockingpub use client::WhoisClient;blockingpub use client::WhoisClientBuilder;blockingpub use client::AsyncChecker;asyncpub use client::AsyncWhoisClient;asyncpub use client::AsyncWhoisClientBuilder;asyncpub use parser::Contact;parserpub use parser::WhoisRecord;parser
Modules§
- cache
- Caching responses, so a repeated question costs nothing.
- client
- The facade: one object that ties the other layers together.
- detect
- Deciding what a response actually said.
- domain
- Value objects: the vocabulary the rest of the crate is written in.
- error
- The error type returned by every fallible operation in this crate.
- parser
parser - Turning a response into a
WhoisRecord. - rdap
rdap - The RDAP response model of RFC 9083.
- registry
- Which registry serves which suffix, and how to reach it.
- transport
- Talking to servers: the only part of the crate that performs I/O.
Constants§
- VERSION
- The crate version, from
Cargo.toml.
Functions§
- availability
blocking - The availability of one domain, with a default client.
- is_
available blocking - Whether one domain is free to register, with a default client.
- lookup
blocking - Look one domain up with a default client.