summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-07-25 21:17:33 -0400
committerGalen Guyer <galen@galenguyer.com>2022-07-25 21:17:56 -0400
commitb4eb857f107866143b0b06d7c6f3744aea50da02 (patch)
tree48b1bf3e69c2b22e4a7756bff89c95160325f98c
parentc4a4f360dbf1f2742c33e551a42de8a70e07d506 (diff)
Use whois query to ensure domain validity
-rw-r--r--Cargo.lock271
-rw-r--r--Cargo.toml4
-rw-r--r--data/whois-servers.json793
-rw-r--r--src/main.rs10
-rw-r--r--src/routes/v1/zones.rs40
5 files changed, 1114 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c6acc8a..8acab35 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,6 +24,15 @@ dependencies = [
]
[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -198,7 +207,7 @@ dependencies = [
"num-integer",
"num-traits",
"serde",
- "time",
+ "time 0.1.43",
"winapi",
]
@@ -289,6 +298,12 @@ dependencies = [
]
[[package]]
+name = "data-encoding"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
+
+[[package]]
name = "digest"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -335,12 +350,56 @@ dependencies = [
]
[[package]]
+name = "educe"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c07b7cc9cd8c08d10db74fca3b20949b9b6199725c04a0cce6d543496098fcac"
+dependencies = [
+ "enum-ordinalize",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
+name = "endian-type"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
+
+[[package]]
+name = "enum-as-inner"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "enum-ordinalize"
+version = "3.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2170fc0efee383079a8bdd05d6ea2a184d2a0f07a1c1dcabdb2fd5e9f24bc36c"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn",
+]
+
+[[package]]
name = "event-listener"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -414,6 +473,12 @@ dependencies = [
]
[[package]]
+name = "futures-io"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
+
+[[package]]
name = "futures-sink"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -436,6 +501,7 @@ dependencies = [
"futures-task",
"pin-project-lite",
"pin-utils",
+ "slab",
]
[[package]]
@@ -479,7 +545,7 @@ dependencies = [
[[package]]
name = "hdt-api"
-version = "0.1.3"
+version = "0.1.4"
dependencies = [
"addr",
"anyhow",
@@ -504,6 +570,8 @@ dependencies = [
"tower-http",
"tracing-subscriber",
"uuid",
+ "whois-rust",
+ "whoisthere",
]
[[package]]
@@ -651,6 +719,12 @@ dependencies = [
]
[[package]]
+name = "ipnet"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
+
+[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -801,6 +875,15 @@ dependencies = [
]
[[package]]
+name = "nibble_vec"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
name = "nom"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -820,6 +903,17 @@ dependencies = [
]
[[package]]
+name = "num-bigint"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -849,6 +943,15 @@ dependencies = [
]
[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "once_cell"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1037,6 +1140,16 @@ dependencies = [
]
[[package]]
+name = "radix_trie"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
+dependencies = [
+ "endian-type",
+ "nibble_vec",
+]
+
+[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1087,6 +1200,23 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+
+[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1096,6 +1226,15 @@ dependencies = [
]
[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
name = "ryu"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1141,6 +1280,12 @@ dependencies = [
]
[[package]]
+name = "semver"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
+
+[[package]]
name = "serde"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1224,6 +1369,15 @@ dependencies = [
]
[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1429,6 +1583,16 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
+dependencies = [
+ "libc",
+ "num_threads",
+]
+
+[[package]]
name = "tinyvec"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1618,6 +1782,51 @@ dependencies = [
]
[[package]]
+name = "trust-dns-client"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6d9ba1c6079f6f9b4664e482db1700bd53d2ee77b1c9752c1d7a66c0c8bda99"
+dependencies = [
+ "cfg-if",
+ "data-encoding",
+ "futures-channel",
+ "futures-util",
+ "lazy_static",
+ "log",
+ "radix_trie",
+ "rand",
+ "thiserror",
+ "time 0.3.11",
+ "tokio",
+ "trust-dns-proto",
+]
+
+[[package]]
+name = "trust-dns-proto"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d"
+dependencies = [
+ "async-trait",
+ "cfg-if",
+ "data-encoding",
+ "enum-as-inner",
+ "futures-channel",
+ "futures-io",
+ "futures-util",
+ "idna",
+ "ipnet",
+ "lazy_static",
+ "log",
+ "rand",
+ "smallvec",
+ "thiserror",
+ "tinyvec",
+ "tokio",
+ "url",
+]
+
+[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1685,6 +1894,41 @@ dependencies = [
]
[[package]]
+name = "validators"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a608a36865089e56a81675b11129cfac8f410d1afcf52f07e1662af75634c691"
+dependencies = [
+ "idna",
+ "validators-derive",
+ "validators-options",
+]
+
+[[package]]
+name = "validators-derive"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a677309c30754937e1164d730b8b3fcf6a7fbc26fcfe141c52b06aeae4743b9"
+dependencies = [
+ "educe",
+ "enum-ordinalize",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "validators-options",
+]
+
+[[package]]
+name = "validators-options"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad273b68c2810b6bc92a6df4008505849bf02d5723381156871e9729616d2523"
+dependencies = [
+ "educe",
+ "enum-ordinalize",
+]
+
+[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1799,6 +2043,29 @@ dependencies = [
]
[[package]]
+name = "whois-rust"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf31968a3b3d30e115707b8857f0a4e19cc67235ad29f659c91dd4713213c5d6"
+dependencies = [
+ "once_cell",
+ "regex",
+ "serde_json",
+ "trust-dns-client",
+ "validators",
+]
+
+[[package]]
+name = "whoisthere"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dea492e2aa1beb56ebcd94341685bb8641181c45ebd33548f3249b558ca59113"
+dependencies = [
+ "chrono",
+ "regex",
+]
+
+[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 410b520..0658f47 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "hdt-api"
-version = "0.1.3"
+version = "0.1.4"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -30,5 +30,7 @@ tower-http = { version = "0.3.3", features = ["cors", "trace"] }
tracing-subscriber = "0.3.11"
# uuid v1.0.0 is out, but it breaks sqlx... we just have to wait for sqlx to release v0.6
uuid = { version = "0.8.2", features = ["serde", "v4"] }
+whois-rust = "1.5.0"
+whoisthere = "0.1.3"
[features]
diff --git a/data/whois-servers.json b/data/whois-servers.json
new file mode 100644
index 0000000..651e88d
--- /dev/null
+++ b/data/whois-servers.json
@@ -0,0 +1,793 @@
+{
+ "br.com": "whois.centralnic.net",
+ "cn.com": "whois.centralnic.net",
+ "de.com": "whois.centralnic.net",
+ "eu.com": "whois.centralnic.net",
+ "gb.com": "whois.centralnic.net",
+ "gb.net": "whois.centralnic.net",
+ "gr.com": "whois.centralnic.net",
+ "hu.com": "whois.centralnic.net",
+ "in.net": "whois.centralnic.net",
+ "jpn.com": "whois.centralnic.net",
+ "no.com": "whois.centralnic.net",
+ "qc.com": "whois.centralnic.net",
+ "ru.com": "whois.centralnic.net",
+ "sa.com": "whois.centralnic.net",
+ "se.com": "whois.centralnic.net",
+ "se.net": "whois.centralnic.net",
+ "uk.com": "whois.centralnic.net",
+ "uk.net": "whois.centralnic.net",
+ "us.com": "whois.centralnic.net",
+ "uy.com": "whois.centralnic.net",
+ "web.com": "whois.centralnic.net",
+ "za.com": "whois.centralnic.net",
+ "com": {
+ "host": "whois.verisign-grs.com",
+ "query": "DOMAIN $addr\r\n"
+ },
+
+ "za.net": "whois.za.net",
+ "net": {
+ "host": "whois.verisign-grs.com",
+ "query": "DOMAIN $addr\r\n"
+ },
+
+ "eu.org": "whois.eu.org",
+ "za.org": "whois.za.org",
+ "org": "whois.pir.org",
+
+ "edu": "whois.educause.edu",
+ "gov": "whois.dotgov.gov",
+ "int": "whois.iana.org",
+ "mil": null,
+
+ "e164.arpa": "whois.ripe.net",
+ "in-addr.arpa": null,
+ "arpa": "whois.iana.org",
+
+ "aero": "whois.aero",
+ "asia": "whois.nic.asia",
+ "biz": "whois.biz",
+ "cat": "whois.cat",
+ "coop": "whois.nic.coop",
+ "info": "whois.afilias.net",
+ "jobs": "jobswhois.verisign-grs.com",
+ "mobi": "whois.dotmobiregistry.net",
+ "museum": "whois.museum",
+ "name": "whois.nic.name",
+ "post": "whois.dotpostregistry.net",
+ "pro": "whois.afilias.net",
+ "tel": "whois.nic.tel",
+ "travel": "whois.nic.travel",
+ "xxx": "whois.nic.xxx",
+
+ "academy": "whois.nic.academy",
+ "accountants": "whois.nic.accountants",
+ "actor": "whois.nic.actor",
+ "agency": "whois.nic.agency",
+ "airforce": "whois.nic.airforce",
+ "apartments": "whois.nic.apartments",
+ "app": "whois.nic.google",
+ "archi": "whois.nic.archi",
+ "army": "whois.nic.army",
+ "associates": "whois.nic.associates",
+ "attorney": "whois.nic.attorney",
+ "auction": "whois.nic.auction",
+ "audio": "whois.nic.audio",
+ "autos": "whois.nic.autos",
+ "axa": "whois.nic.axa",
+ "band": "whois.nic.band",
+ "bar": "whois.nic.bar",
+ "bargains": "whois.nic.bargains",
+ "bayern": "whois.nic.bayern",
+ "beer": "whois.nic.beer",
+ "berlin": "whois.nic.berlin",
+ "best": "whois.nic.best",
+ "bid": "whois.nic.bid",
+ "bike": "whois.nic.bike",
+ "bingo": "whois.nic.bingo",
+ "black": "whois.nic.black",
+ "blackfriday": "whois.nic.blackfriday",
+ "blog": "whois.nic.blog",
+ "blue": "whois.nic.blue",
+ "boutique": "whois.nic.boutique",
+ "build": "whois.nic.build",
+ "builders": "whois.nic.builders",
+ "business": "whois.nic.business",
+ "buzz": "whois.nic.buzz",
+ "cab": "whois.nic.cab",
+ "cafe": "whois.nic.cafe",
+ "camera": "whois.nic.camera",
+ "camp": "whois.nic.camp",
+ "capital": "whois.nic.capital",
+ "cards": "whois.nic.cards",
+ "care": "whois.nic.care",
+ "career": "whois.nic.career",
+ "careers": "whois.nic.careers",
+ "cash": "whois.nic.cash",
+ "casino": "whois.nic.casino",
+ "catering": "whois.nic.catering",
+ "center": "whois.nic.center",
+ "ceo": "whois.nic.ceo",
+ "charity": "whois.nic.charity",
+ "chat": "whois.nic.chat",
+ "cheap": "whois.nic.cheap",
+ "christmas": "whois.nic.christmas",
+ "church": "whois.nic.church",
+ "citic": "whois.nic.citic",
+ "city": "whois.nic.city",
+ "claims": "whois.nic.claims",
+ "cleaning": "whois.nic.cleaning",
+ "clinic": "whois.nic.clinic",
+ "clothing": "whois.nic.clothing",
+ "cloud": "whois.nic.cloud",
+ "club": "whois.nic.club",
+ "coach": "whois.nic.coach",
+ "codes": "whois.nic.codes",
+ "coffee": "whois.nic.coffee",
+ "college": "whois.nic.college",
+ "cologne": "whois.nic.cologne",
+ "community": "whois.nic.community",
+ "company": "whois.nic.company",
+ "computer": "whois.nic.computer",
+ "condos": "whois.nic.condos",
+ "construction": "whois.nic.construction",
+ "consulting": "whois.nic.consulting",
+ "contractors": "whois.nic.contractors",
+ "cooking": "whois.nic.cooking",
+ "cool": "whois.nic.cool",
+ "country": "whois.nic.country",
+ "coupons": "whois.nic.coupons",
+ "credit": "whois.nic.credit",
+ "creditcard": "whois.nic.creditcard",
+ "cruises": "whois.nic.cruises",
+ "dance": "whois.nic.dance",
+ "dating": "whois.nic.dating",
+ "deals": "whois.nic.deals",
+ "degree": "whois.nic.degree",
+ "delivery": "whois.nic.delivery",
+ "democrat": "whois.nic.democrat",
+ "dental": "whois.nic.dental",
+ "dentist": "whois.nic.dentist",
+ "desi": "whois.nic.desi",
+ "dev": "whois.nic.google",
+ "diamonds": "whois.nic.diamonds",
+ "digital": "whois.donuts.co",
+ "direct": "whois.nic.direct",
+ "directory": "whois.nic.directory",
+ "discount": "whois.nic.discount",
+ "dnp": "whois.nic.dnp",
+ "doctor": "whois.nic.doctor",
+ "dog": "whois.nic.dog",
+ "domains": "whois.nic.domains",
+ "education": "whois.nic.education",
+ "email": "whois.nic.email",
+ "energy": "whois.nic.energy",
+ "engineer": "whois.nic.engineer",
+ "engineering": "whois.nic.engineering",
+ "enterprises": "whois.nic.enterprises",
+ "equipment": "whois.nic.equipment",
+ "estate": "whois.nic.estate",
+ "eus": "whois.nic.eus",
+ "events": "whois.nic.events",
+ "exchange": "whois.nic.exchange",
+ "expert": "whois.nic.expert",
+ "exposed": "whois.nic.exposed",
+ "express": "whois.nic.express",
+ "fail": "whois.nic.fail",
+ "family": "whois.nic.family",
+ "fan": "whois.nic.fan",
+ "farm": "whois.nic.farm",
+ "feedback": "whois.nic.feedback",
+ "finance": "whois.nic.finance",
+ "financial": "whois.nic.financial",
+ "fish": "whois.nic.fish",
+ "fishing": "whois.nic.fishing",
+ "fitness": "whois.nic.fitness",
+ "flights": "whois.nic.flights",
+ "florist": "whois.nic.florist",
+ "foo": "whois.nic.foo",
+ "football": "whois.nic.football",
+ "forsale": "whois.nic.forsale",
+ "foundation": "whois.nic.foundation",
+ "frogans": "whois.nic.frogans",
+ "fun": "whois.nic.fun",
+ "fund": "whois.nic.fund",
+ "furniture": "whois.nic.furniture",
+ "futbol": "whois.nic.futbol",
+ "fyi": "whois.nic.fyi",
+ "gal": "whois.nic.gal",
+ "gallery": "whois.nic.gallery",
+ "games": "whois.nic.games",
+ "gift": "whois.nic.gift",
+ "gifts": "whois.nic.gifts",
+ "gives": "whois.nic.gives",
+ "glass": "whois.nic.glass",
+ "global": "whois.nic.global",
+ "globo": "whois.nic.globo",
+ "gmbh": "whois.nic.gmbh",
+ "gmo": "whois.nic.gmo",
+ "gold": "whois.nic.gold",
+ "golf": "whois.nic.golf",
+ "gop": "whois.nic.gop",
+ "graphics": "whois.nic.graphics",
+ "gratis": "whois.nic.gratis",
+ "gripe": "whois.nic.gripe",
+ "group": "whois.nic.group",
+ "guide": "whois.nic.guide",
+ "guitars": "whois.nic.guitars",
+ "guru": "whois.nic.guru",
+ "haus": "whois.nic.haus",
+ "healthcare": "whois.nic.healthcare",
+ "hiphop": "whois.nic.hiphop",
+ "hockey": "whois.nic.hockey",
+ "holdings": "whois.nic.holdings",
+ "holiday": "whois.nic.holiday",
+ "homes": "whois.nic.homes",
+ "horse": "whois.nic.horse",
+ "hospital": "whois.nic.hospital",
+ "host": "whois.nic.host",
+ "house": "whois.nic.house",
+ "immo": "whois.nic.immo",
+ "immobilien": "whois.nic.immobilien",
+ "industries": "whois.nic.industries",
+ "ink": "whois.nic.ink",
+ "institute": "whois.nic.institute",
+ "insure": "whois.nic.insure",
+ "international": "whois.nic.international",
+ "investments": "whois.nic.investments",
+ "irish": "whois.nic.irish",
+ "jetzt": "whois.nic.jetzt",
+ "jewelry": "whois.nic.jewelry",
+ "juegos": "whois.nic.juegos",
+ "kaufen": "whois.nic.kaufen",
+ "kim": "whois.nic.kim",
+ "kitchen": "whois.nic.kitchen",
+ "kiwi": "whois.nic.kiwi",
+ "koeln": "whois.nic.koeln",
+ "kred": "whois.nic.kred",
+ "land": "whois.nic.land",
+ "lawyer": "whois.nic.lawyer",
+ "lease": "whois.nic.lease",
+ "legal": "whois.nic.legal",
+ "life": "whois.nic.life",
+ "lighting": "whois.nic.lighting",
+ "limited": "whois.nic.limited",
+ "limo": "whois.nic.limo",
+ "link": "whois.nic.link",
+ "live": "whois.nic.live",
+ "loans": "whois.nic.loans",
+ "london": "whois.nic.london",
+ "love": "whois.nic.love",
+ "ltd": "whois.nic.ltd",
+ "luxe": "whois.nic.luxe",
+ "luxury": "whois.nic.luxury",
+ "maison": "whois.nic.maison",
+ "management": "whois.nic.management",
+ "mango": "whois.nic.mango",
+ "market": "whois.nic.market",
+ "marketing": "whois.nic.marketing",
+ "mba": "whois.nic.mba",
+ "media": "whois.nic.media",
+ "meet": "whois.nic.meet",
+ "memorial": "whois.nic.memorial",
+ "menu": "whois.nic.menu",
+ "miami": "whois.nic.miami",
+ "moda": "whois.nic.moda",
+ "moe": "whois.nic.moe",
+ "monash": "whois.nic.monash",
+ "money": "whois.nic.money",
+ "mortgage": "whois.nic.mortgage",
+ "moscow": "whois.nic.moscow",
+ "motorcycles": "whois.nic.motorcycles",
+ "movie": "whois.nic.movie",
+ "nagoya": "whois.nic.nagoya",
+ "navy": "whois.nic.navy",
+ "network": "whois.nic.network",
+ "neustar": "whois.nic.neustar",
+ "news": "whois.nic.news",
+ "ninja": "whois.nic.ninja",
+ "nyc": "whois.nic.nyc",
+ "okinawa": "whois.nic.okinawa",
+ "one": "whois.nic.one",
+ "onl": "whois.nic.onl",
+ "online": "whois.centralnic.net",
+ "paris": "whois.nic.paris",
+ "partners": "whois.nic.partners",
+ "parts": "whois.nic.parts",
+ "photo": "whois.nic.photo",
+ "photography": "whois.nic.photography",
+ "photos": "whois.nic.photos",
+ "pics": "whois.nic.pics",
+ "pictures": "whois.nic.pictures",
+ "pink": "whois.nic.pink",
+ "pizza": "whois.nic.pizza",
+ "place": "whois.nic.place",
+ "plumbing": "whois.nic.plumbing",
+ "plus": "whois.nic.plus",
+ "press": "whois.nic.press",
+ "productions": "whois.nic.productions",
+ "properties": "whois.nic.properties",
+ "pub": "whois.nic.pub",
+ "qpon": "whois.nic.qpon",
+ "quebec": "whois.nic.quebec",
+ "recipes": "whois.nic.recipes",
+ "red": "whois.nic.red",
+ "rehab": "whois.nic.rehab",
+ "reise": "whois.nic.reise",
+ "reisen": "whois.nic.reisen",
+ "ren": "whois.nic.ren",
+ "rentals": "whois.nic.rentals",
+ "repair": "whois.nic.repair",
+ "report": "whois.nic.report",
+ "republican": "whois.nic.republican",
+ "rest": "whois.nic.rest",
+ "restaurant": "whois.nic.restaurant",
+ "reviews": "whois.nic.reviews",
+ "rich": "whois.nic.rich",
+ "rio": "whois.nic.rio",
+ "rip": "whois.nic.rip",
+ "rocks": "whois.nic.rocks",
+ "rodeo": "whois.nic.rodeo",
+ "ruhr": "whois.nic.ruhr",
+ "run": "whois.nic.run",
+ "ryukyu": "whois.nic.ryukyu",
+ "saarland": "whois.nic.saarland",
+ "sale": "whois.nic.sale",
+ "salon": "whois.nic.salon",
+ "sarl": "whois.nic.sarl",
+ "school": "whois.nic.school",
+ "schule": "whois.nic.schule",
+ "services": "whois.nic.services",
+ "sexy": "whois.nic.sexy",
+ "shiksha": "whois.nic.shiksha",
+ "shoes": "whois.nic.shoes",
+ "shopping": "whois.nic.shopping",
+ "show": "whois.nic.show",
+ "singles": "whois.nic.singles",
+ "site": "whois.nic.site",
+ "soccer": "whois.nic.soccer",
+ "social": "whois.nic.social",
+ "software": "whois.nic.software",
+ "sohu": "whois.nic.sohu",
+ "solar": "whois.nic.solar",
+ "solutions": "whois.nic.solutions",
+ "soy": "whois.nic.soy",
+ "space": "whois.nic.space",
+ "sport": "whois.nic.sport",
+ "store": "whois.nic.store",
+ "studio": "whois.nic.studio",
+ "style": "whois.nic.style",
+ "supplies": "whois.nic.supplies",
+ "supply": "whois.nic.supply",
+ "support": "whois.nic.support",
+ "surgery": "whois.nic.surgery",
+ "systems": "whois.nic.systems",
+ "tattoo": "whois.nic.tattoo",
+ "tax": "whois.nic.tax",
+ "taxi": "whois.nic.taxi",
+ "team": "whois.nic.team",
+ "tech": "whois.nic.tech",
+ "technology": "whois.nic.technology",
+ "tennis": "whois.nic.tennis",
+ "theater": "whois.nic.theater",
+ "tienda": "whois.nic.tienda",
+ "tips": "whois.nic.tips",
+ "tires": "whois.nic.tires",
+ "today": "whois.nic.today",
+ "tokyo": "whois.nic.tokyo",
+ "tools": "whois.nic.tools",
+ "top": "whois.nic.top",
+ "tours": "whois.nic.tours",
+ "town": "whois.nic.town",
+ "toys": "whois.nic.toys",
+ "trade": "whois.nic.trade",
+ "training": "whois.nic.training",
+ "university": "whois.nic.university",
+ "uno": "whois.nic.uno",
+ "vacations": "whois.nic.vacations",
+ "vegas": "whois.nic.vegas",
+ "ventures": "whois.nic.ventures",
+ "versicherung": "whois.nic.versicherung",
+ "vet": "whois.nic.vet",
+ "viajes": "whois.nic.viajes",
+ "video": "whois.nic.video",
+ "villas": "whois.nic.villas",
+ "vin": "whois.nic.vin",
+ "vip": "whois.nic.vip",
+ "vision": "whois.nic.vision",
+ "vodka": "whois.nic.vodka",
+ "vote": "whois.nic.vote",
+ "voting": "whois.nic.voting",
+ "voto": "whois.nic.voto",
+ "voyage": "whois.nic.voyage",
+ "wang": "whois.nic.wang",
+ "watch": "whois.nic.watch",
+ "webcam": "whois.nic.webcam",
+ "website": "whois.nic.website",
+ "wed": "whois.nic.wed",
+ "wien": "whois.nic.wien",
+ "wiki": "whois.nic.wiki",
+ "wine": "whois.nic.wine",
+ "works": "whois.nic.works",
+ "world": "whois.nic.world",
+ "wtc": "whois.nic.wtc",
+ "wtf": "whois.nic.wtf",
+ "xn--3bst00m": "whois.nic.xn--3bst00m",
+ "xn--3ds443g": "whois.nic.xn--3ds443g",
+ "xn--55qw42g": "whois.nic.xn--55qw42g",
+ "xn--55qx5d": "whois.nic.xn--55qx5d",
+ "xn--6frz82g": "whois.nic.xn--6frz82g",
+ "xn--6qq986b3xl": "whois.nic.xn--6qq986b3xl",
+ "xn--80adxhks": "whois.nic.xn--80adxhks",
+ "xn--80asehdb": "whois.nic.xn--80asehdb",
+ "xn--80aswg": "whois.nic.xn--80aswg",
+ "xn--c1avg": "whois.nic.xn--c1avg",
+ "xn--cg4bki": "whois.nic.xn--cg4bki",
+ "xn--czrs0t": "whois.nic.xn--czrs0t",
+ "xn--czr694b": "whois.nic.xn--czr694b",
+ "xn--czru2d": "whois.nic.xn--czru2d",
+ "xn--d1acj3b": "whois.nic.xn--d1acj3b",
+ "xn--fiq228c5hs": "whois.nic.xn--fiq228c5hs",
+ "xn--fiq64b": "whois.nic.xn--fiq64b",
+ "xn--i1b6b1a6a2e": "whois.nic.xn--i1b6b1a6a2e",
+ "xn--io0a7i": "whois.nic.xn--io0a7i",
+ "xn--mgbab2bd": "whois.nic.xn--mgbab2bd",
+ "xn--ngbc5azd": "whois.nic.xn--ngbc5azd",
+ "xn--nqv7f": "whois.nic.xn--nqv7f",
+ "xn--nqv7fs00ema": "whois.nic.xn--nqv7fs00ema",
+ "xn--q9jyb4c": "whois.nic.xn--q9jyb4c",
+ "xn--rhqv96g": "whois.nic.xn--rhqv96g",
+ "xn--ses554g": "whois.nic.xn--ses554g",
+ "xn--unup4y": "whois.nic.xn--unup4y",
+ "xn--vhquv": "whois.nic.xn--vhquv",
+ "xn--zfr164b": "whois.nic.xn--zfr164b",
+ "xyz": "whois.nic.xyz",
+ "yachts": "whois.nic.yachts",
+ "yokohama": "whois.nic.yokohama",
+ "zone": "whois.nic.zone",
+
+ "ac": "whois.nic.ac",
+ "ad": null,
+ "ae": "whois.aeda.net.ae",
+ "af": "whois.nic.af",
+ "ag": "whois.nic.ag",
+ "ai": "whois.nic.ai",
+ "al": null,
+ "am": "whois.amnic.net",
+ "an": null,
+ "ao": null,
+ "aq": null,
+ "ar": null,
+ "as": "whois.nic.as",
+ "priv.at": "whois.nic.priv.at",
+ "at": "whois.nic.at",
+ "au": "whois.auda.org.au",
+ "aw": "whois.nic.aw",
+ "ax": "whois.ax",
+ "az": null,
+ "ba": null,
+ "bb": null,
+ "bd": null,
+ "be": "whois.dns.be",
+ "bf": null,
+ "bg": "whois.register.bg",
+ "bh": null,
+ "bi": "whois1.nic.bi",
+ "bj": "whois.nic.bj",
+ "bl": null,
+ "bm": "whois.afilias-srs.net",
+ "bn": "whois.bn",
+ "bo": "whois.nic.bo",
+ "bq": null,
+ "br": "whois.registro.br",
+ "bs": null,
+ "bt": null,
+ "bv": null,
+ "by": "whois.cctld.by",
+ "bw": "whois.nic.net.bw",
+ "bz": "whois.afilias-grs.info",
+ "co.ca": "whois.co.ca",
+ "ca": "whois.cira.ca",
+ "cc": "ccwhois.verisign-grs.com",
+ "cd": "whois.nic.cd",
+ "cf": "whois.dot.cf",
+ "cg": null,
+ "ch": "whois.nic.ch",
+ "ci": "whois.nic.ci",
+ "ck": null,
+ "cl": "whois.nic.cl",
+ "cm": "whois.netcom.cm",
+ "edu.cn": "whois.edu.cn",
+ "cn": "whois.cnnic.cn",
+ "uk.co": "whois.uk.co",
+ "co": "whois.nic.co",
+ "cr": "whois.nic.cr",
+ "cu": null,
+ "cv": null,
+ "cw": null,
+ "cx": "whois.nic.cx",
+ "cy": null,
+ "cz": "whois.nic.cz",
+ "de": {
+ "host": "whois.denic.de",
+ "query": "-T dn $addr\r\n",
+ "punycode": false
+ },
+ "dj": null,
+ "dk": {
+ "host": "whois.dk-hostmaster.dk",
+ "query": "--charset=utf-8 --show-handles $addr\r\n"
+ },
+ "dm": "whois.nic.dm",
+ "do": "whois.nic.do",
+ "dz": "whois.nic.dz",
+ "ec": "whois.nic.ec",
+ "ee": "whois.tld.ee",
+ "eg": null,
+ "eh": null,
+ "er": null,
+ "es": null,
+ "et": null,
+ "eu": "whois.eu",
+ "fi": "whois.fi",
+ "fj": "whois.usp.ac.fj",
+ "fk": null,
+ "fm": "whois.nic.fm",
+ "fo": "whois.nic.fo",
+ "fr": "whois.nic.fr",
+ "ga": "whois.dot.ga",
+ "gb": null,
+ "gd": "whois.nic.gd",
+ "ge": "whois.nic.ge",
+ "gf": "whois.mediaserv.net",
+ "gg": "whois.gg",
+ "gh": "whois.nic.gh",
+ "gi": "whois.afilias-grs.info",
+ "gl": "whois.nic.gl",
+ "gm": null,
+ "gn": null,
+ "gp": "whois.nic.gp",
+ "gq": "whois.dominio.gq",
+ "gr": null,
+ "gs": "whois.nic.gs",
+ "gt": null,
+ "gu": null,
+ "gw": null,
+ "gy": "whois.registry.gy",
+ "hk": "whois.hkirc.hk",
+ "hm": "whois.registry.hm",
+ "hn": "whois.nic.hn",
+ "hr": "whois.dns.hr",
+ "ht": "whois.nic.ht",
+ "hu": "whois.nic.hu",
+ "id": "whois.pandi.or.id",
+ "ie": "whois.domainregistry.ie",
+ "il": "whois.isoc.org.il",
+ "im": "whois.nic.im",
+ "in": "whois.registry.in",
+ "io": "whois.nic.io",
+ "iq": "whois.cmc.iq",
+ "ir": "whois.nic.ir",
+ "is": "whois.isnic.is",
+ "it": "whois.nic.it",
+ "je": "whois.je",
+ "jm": null,
+ "jo": null,
+ "jp": {
+ "host": "whois.jprs.jp",
+ "query": "$addr/e\r\n"
+ },
+ "ke": "whois.kenic.or.ke",
+ "kg": "whois.domain.kg",
+ "kh": null,
+ "ki": "whois.nic.ki",
+ "km": null,
+ "kn": "whois.nic.kn",
+ "kp": null,
+ "kr": "whois.kr",
+ "kw": null,
+ "ky": "whois.kyregistry.ky",
+ "kz": "whois.nic.kz",
+ "la": "whois.nic.la",
+ "lb": null,
+ "lc": "whois.afilias-grs.info",
+ "li": "whois.nic.li",
+ "lk": "whois.nic.lk",
+ "lr": null,
+ "ls": "whois.nic.ls",
+ "lt": "whois.domreg.lt",
+ "lu": "whois.dns.lu",
+ "lv": "whois.nic.lv",
+ "ly": "whois.nic.ly",
+ "ma": "whois.iam.net.ma",
+ "mc": null,
+ "md": "whois.nic.md",
+ "me": "whois.nic.me",
+ "mf": null,
+ "mg": "whois.nic.mg",
+ "mh": null,
+ "mk": "whois.marnet.mk",
+ "ml": "whois.dot.ml",
+ "mm": null,
+ "mn": "whois.nic.mn",
+ "mo": null,
+ "mp": null,
+ "mq": "whois.mediaserv.net",
+ "mr": "whois.nic.mr",
+ "ms": "whois.nic.ms",
+ "mt": null,
+ "mu": "whois.nic.mu",
+ "mv": null,
+ "mw": "whois.nic.mw",
+ "mx": "whois.mx",
+ "my": "whois.domainregistry.my",
+ "mz": "whois.nic.mz",
+ "na": "whois.na-nic.com.na",
+ "nc": "whois.nc",
+ "ne": null,
+ "nf": "whois.nic.nf",
+ "ng": "whois.nic.net.ng",
+ "ni": null,
+ "nl": "whois.domain-registry.nl",
+ "no": {
+ "host": "whois.norid.no",
+ "query": "-c utf-8 $addr\r\n"
+ },
+ "np": null,
+ "nr": null,
+ "nu": "whois.iis.nu",
+ "nz": "whois.srs.net.nz",
+ "om": "whois.registry.om",
+ "pa": null,
+ "pe": "kero.yachay.pe",
+ "pf": "whois.registry.pf",
+ "pg": null,
+ "ph": null,
+ "pk": null,
+ "co.pl": "whois.co.pl",
+ "pl": "whois.dns.pl",
+ "pm": "whois.nic.pm",
+ "pn": null,
+ "pr": "whois.nic.pr",
+ "ps": "whois.pnina.ps",
+ "pt": "whois.dns.pt",
+ "pw": "whois.nic.pw",
+ "py": null,
+ "qa": "whois.registry.qa",
+ "re": "whois.nic.re",
+ "ro": "whois.rotld.ro",
+ "rs": "whois.rnids.rs",
+ "edu.ru": "whois.informika.ru",
+ "ru": "whois.tcinet.ru",
+ "rw": "whois.ricta.org.rw",
+ "sa": "whois.nic.net.sa",
+ "sb": "whois.nic.sb",
+ "sc": "whois.afilias-grs.info",
+ "sd": null,
+ "se": "whois.iis.se",
+ "sg": "whois.sgnic.sg",
+ "sh": "whois.nic.sh",
+ "si": "whois.arnes.si",
+ "sj": null,
+ "sk": "whois.sk-nic.sk",
+ "sl": "whois.nic.sl",
+ "sm": "whois.nic.sm",
+ "sn": "whois.nic.sn",
+ "so": "whois.nic.so",
+ "sr": null,
+ "ss": "whois.nic.ss",
+ "st": "whois.nic.st",
+ "su": "whois.tcinet.ru",
+ "sv": null,
+ "sx": "whois.sx",
+ "sy": "whois.tld.sy",
+ "sz": null,
+ "tc": "whois.nic.tc",
+ "td": "whois.nic.td",
+ "tf": "whois.nic.tf",
+ "tg": "whois.nic.tg",
+ "th": "whois.thnic.co.th",
+ "tj": null,
+ "tk": "whois.dot.tk",
+ "tl": "whois.nic.tl",
+ "tm": "whois.nic.tm",
+ "tn": "whois.ati.tn",
+ "to": "whois.tonic.to",
+ "tp": null,
+ "tr": "whois.nic.tr",
+ "tt": null,
+ "tv": "tvwhois.verisign-grs.com",
+ "tw": "whois.twnic.net.tw",
+ "tz": "whois.tznic.or.tz",
+ "biz.ua": "whois.biz.ua",
+ "co.ua": "whois.co.ua",
+ "pp.ua": "whois.pp.ua",
+ "ua": "whois.ua",
+ "ug": "whois.co.ug",
+ "ac.uk": "whois.ja.net",
+ "bl.uk": null,
+ "british-library.uk": null,
+ "gov.uk": "whois.ja.net",
+ "icnet.uk": null,
+ "jet.uk": null,
+ "mod.uk": null,
+ "nhs.uk": null,
+ "nls.uk": null,
+ "parliament.uk": null,
+ "police.uk": null,
+ "uk": "whois.nic.uk",
+ "um": null,
+ "fed.us": "whois.nic.gov",
+ "us": "whois.nic.us",
+ "com.uy": null,
+ "uy": "whois.nic.org.uy",
+ "uz": "whois.cctld.uz",
+ "va": null,
+ "vc": "whois.afilias-grs.info",
+ "ve": "whois.nic.ve",
+ "vg": "whois.nic.vg",
+ "vi": null,
+ "vn": null,
+ "vu": "vunic.vu",
+ "wf": "whois.nic.wf",
+ "ws": "whois.website.ws",
+ "ye": null,
+ "yt": "whois.nic.yt",
+ "ac.za": "whois.ac.za",
+ "alt.za": "whois.alt.za",
+ "co.za": "whois.registry.net.za",
+ "gov.za": "whois.gov.za",
+ "net.za": "whois.net.za",
+ "org.za": null,
+ "web.za": "whois.web.za",
+ "za": null,
+ "zm": "whois.nic.zm",
+ "zw": null,
+
+ "xn--3e0b707e": "whois.kr",
+ "xn--45brj9c": "whois.inregistry.net",
+ "xn--80ao21a": "whois.nic.kz",
+ "xn--90a3ac": "whois.rnids.rs",
+ "xn--clchc0ea0b2g2a9gcd": "whois.sgnic.sg",
+ "xn--fiqs8s": "cwhois.cnnic.cn",
+ "xn--fiqz9s": "cwhois.cnnic.cn",
+ "xn--fpcrj9c3d": "whois.inregistry.net",
+ "xn--fzc2c9e2c": "whois.nic.lk",
+ "xn--gecrj9c": "whois.inregistry.net",
+ "xn--h2brj9c": "whois.inregistry.net",
+ "xn--j1amh": "whois.dotukr.com",
+ "xn--j6w193g": "whois.hkirc.hk",
+ "xn--kprw13d": "whois.twnic.net.tw",
+ "xn--kpry57d": "whois.twnic.net.tw",
+ "xn--l1acc": "whois.nic.mn",
+ "xn--lgbbat1ad8j": "whois.nic.dz",
+ "xn--mgb9awbf": "whois.registry.om",
+ "xn--mgba3a4f16a": "whois.nic.ir",
+ "xn--mgbaam7a8h": "whois.aeda.net.ae",
+ "xn--mgbayh7gpa": null,
+ "xn--mgbbh1a71e": "whois.inregistry.net",
+ "xn--mgbc0a9azcg": null,
+ "xn--mgberp4a5d4ar": "whois.nic.net.sa",
+ "xn--mgbx4cd0ab": "whois.domainregistry.my",
+ "xn--o3cw4h": "whois.thnic.co.th",
+ "xn--ogbpf8fl": "whois.tld.sy",
+ "xn--p1ai": "whois.tcinet.ru",
+ "xn--pgbs0dh": null,
+ "xn--s9brj9c": "whois.inregistry.net",
+ "xn--wgbh1c": "whois.dotmasr.eg",
+ "xn--wgbl6a": "whois.registry.qa",
+ "xn--xkc2al3hye2a": "whois.nic.lk",
+ "xn--xkc2dl3a5ee0h": "whois.inregistry.net",
+ "xn--yfro4i67o": "whois.sgnic.sg",
+ "xn--ygbi2ammx": "whois.pnina.ps",
+
+ "": "whois.ripe.net",
+
+ "_": {
+ "ip": {
+ "host": "whois.arin.net",
+ "query": "n + $addr\r\n"
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 3190db3..e7e2489 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -51,6 +51,13 @@ async fn main() {
);
info!("Postgres pool initialized");
+ // Create our WhoIs client
+ let whois_client = whois_rust::WhoIs::from_string(include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/data/whois-servers.json"
+ )))
+ .unwrap();
+
let app = Router::new()
.nest(
"/api",
@@ -87,7 +94,8 @@ async fn main() {
),
)
.layer(ServiceBuilder::new().layer(TraceLayer::new_for_http()))
- .layer(Extension(pg_pool));
+ .layer(Extension(pg_pool))
+ .layer(Extension(whois_client));
let addr = SocketAddr::from(([0, 0, 0, 0], 8000));
info!("Binding to {addr}");
diff --git a/src/routes/v1/zones.rs b/src/routes/v1/zones.rs
index 5336d28..ddbeb19 100644
--- a/src/routes/v1/zones.rs
+++ b/src/routes/v1/zones.rs
@@ -11,6 +11,7 @@ use serde::Deserialize;
use serde_json::json;
use sqlx::{Error, Pool, Postgres};
use std::sync::Arc;
+use whois_rust::{WhoIs, WhoIsLookupOptions};
lazy_static! {
static ref NAMESERVERS: Vec<String> = Vec::from([
@@ -66,6 +67,7 @@ pub async fn create_zone(
Path(zone_id): Path<String>,
Jwt(user): Jwt,
Extension(pool): Extension<Arc<Pool<Postgres>>>,
+ Extension(whois_client): Extension<WhoIs>,
) -> impl IntoResponse {
let domain = ensure_trailing_dot(&zone_id);
let domain = addr::parse_domain_name(&domain).unwrap();
@@ -87,6 +89,44 @@ pub async fn create_zone(
);
}
+ let lookup = match WhoIsLookupOptions::from_string(&*zone_id.trim_end_matches('.')) {
+ Ok(lookup) => lookup,
+ Err(e) => {
+ return (
+ StatusCode::BAD_REQUEST,
+ Json(json!({
+ "error": "Invalid domain",
+ "message": format!("Could not parse WhoIs Lookup ({})", e)
+ })),
+ )
+ }
+ };
+ let whois_res = match whois_client.lookup(lookup) {
+ Ok(res) => {
+ res
+ }
+ Err(e) => {
+ return (
+ StatusCode::BAD_REQUEST,
+ Json(json!({
+ "error": "Invalid domain",
+ "message": format!("{}", e)
+ })),
+ )
+ }
+ };
+
+ let whois_info = whoisthere::parse_info(&*zone_id.trim_end_matches('.'), &whois_res);
+ if !whois_info.is_registered || whois_info.is_under_grace_period {
+ return (
+ StatusCode::BAD_REQUEST,
+ Json(json!({
+ "error": "Invalid domain",
+ "message": "Domain is not registered or expired"
+ })),
+ )
+ }
+
let zone = db::zones::create_zone(&pool, &zone_id, user.sub).await;
match zone {
Ok(zone) => (StatusCode::OK, Json(json!(zone))),