use crate::Client;
use std::io;
use trillium_http::{KnownHeaderName, Version};
use trillium_server_common::url::Url;
const DNS_MESSAGE: &str = "application/dns-message";
#[derive(Debug, Clone)]
pub(super) struct Doh {
resolver: Url,
http_version: Option<Version>,
}
impl Doh {
pub(super) fn new(resolver: Url, http_version: Option<Version>) -> Self {
Self {
resolver,
http_version,
}
}
pub(super) fn host(&self) -> Option<&str> {
self.resolver.host_str()
}
pub(super) fn resolver(&self) -> &Url {
&self.resolver
}
pub(super) async fn exchange(&self, client: &Client, query: Vec<u8>) -> io::Result<Vec<u8>> {
let mut request = client
.post(self.resolver.as_str())
.with_request_header(KnownHeaderName::ContentType, DNS_MESSAGE)
.with_request_header(KnownHeaderName::Accept, DNS_MESSAGE)
.with_body(query);
if let Some(version) = self.http_version {
request = request.with_http_version(version);
}
let mut conn = request.await.map_err(io::Error::other)?;
log::debug!(
"DoH query to {} over {:?}",
self.resolver,
conn.http_version()
);
conn.response_body()
.read_bytes()
.await
.map_err(io::Error::other)
}
}