use std::io::Read;
use std::net::TcpStream;
use crate::acme::{AcmeManager, CertChoice};
use crate::error::Result;
use crate::net::clienthello::{self, ClientHelloInfo};
const MAX_HELLO: usize = 16 * 1024;
pub(crate) fn read_client_hello(
stream: &mut TcpStream,
) -> Result<Option<(Vec<u8>, ClientHelloInfo)>> {
let mut buf: Vec<u8> = Vec::with_capacity(1024);
let mut tmp = [0u8; 4096];
loop {
if let Some(info) = clienthello::peek(&buf)? {
return Ok(Some((buf, info)));
}
if buf.len() > MAX_HELLO {
return Ok(None);
}
let n = stream.read(&mut tmp)?;
if n == 0 {
return Ok(None);
}
buf.extend_from_slice(&tmp[..n]);
}
}
pub(crate) fn choose(mgr: &AcmeManager, info: &ClientHelloInfo, loopback: bool) -> CertChoice {
if info.wants_acme_tls() {
return match info
.server_name
.as_deref()
.and_then(|h| mgr.challenge_acceptor(h))
{
Some(acceptor) => CertChoice::Serve(acceptor),
None => CertChoice::Reject,
};
}
mgr.choose(info.server_name.as_deref(), loopback)
}