use rocket::State; use rocket::http::Status; use rocket_contrib::json::Json; use trust_dns_client::client::ClientHandle; use trust_dns_client::op::{DnsResponse, ResponseCode}; use trust_dns_client::rr::{DNSClass, Name, RecordType}; use crate::models::dns; use crate::models::errors::{ErrorResponse, make_500}; use crate::models::users::UserInfo; use crate::DnsClient; #[get("/zones//records")] pub async fn get_zone_records( client: State<'_, DnsClient>, user_info: Result, zone: String ) -> Result>, ErrorResponse> { println!("{:#?}", user_info?); // TODO: Implement FromParam for Name let name = Name::from_utf8(&zone).unwrap(); let response: DnsResponse = { let query = client.lock().unwrap().query(name.clone(), DNSClass::IN, RecordType::AXFR); query.await.map_err(make_500)? }; if response.response_code() != ResponseCode::NoError { return ErrorResponse::new( Status::NotFound, format!("zone {} could not be found", name.to_utf8()) ).err() } let answers = response.answers(); let mut records: Vec<_> = answers.to_vec().into_iter() .map(|record| dns::Record::from(record)) .filter(|record| match record.rdata { dns::RData::NULL { .. } | dns::RData::DNSSEC(_) => false, _ => true, }).collect(); // AXFR response ends with SOA, we remove it so it is not doubled in the response. records.pop(); Ok(Json(records)) }