Я пытаюсь найти способ не отвечать на нежелательный запрос (приравниваемый к ddos), закрывая соединение, не сообщая об этом клиенту. Таким образом, стек соединений TIME-WAIT устройства-эмиттера будет расти до тех пор, пока новые соединения больше не будут возможны, в то время как на моей стороне все в порядке.
Я просмотрел руководство actix.rs и документацию docs.rs, но не нашел способа закрыть соединение без ответа, всегда требуется тело. На самом деле у меня есть эта функция как запись по умолчанию:
async fn defaultentry(req: HttpRequest) -> impl Responder {
HttpResponse::build(StatusCode::from_u16(503).unwrap())
.force_close()
.finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(move || {
App::new()
.default_service(
web::get().to(defaultentry)
)
})
.bind(("0.0.0.0", 8080))?
.run()
.await
}
Вы можете вызвать регистрацию обработчика on_connect на HttpServer, чтобы отключите соединение. Насколько я знаю, нет способа сделать это из обработчика.
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(move || {
App::new()
.default_service(
web::get().to(defaultentry)
)
})
.on_connect(|c, _| {
if true { // whatever you're looking for
c.downcast_ref::<TcpStream>().unwrap().shutdown(Shutdown::Both).unwrap();
}
})
.bind(("0.0.0.0", 8080))?
.run()
.await
}
Хм? Любопытно, я использую ржавчину 1.65, и в ней std::net::TcpStream есть .shutdown().
Плохо, я использовал структуру TcpStream Actix-web. Вы правы, это хорошо работает с std::net::TcpStream.
Спасибо, я был далек от хорошей практики. Для последующего использования TcpStream больше не имеет метода .shutdown(), вместо этого используйте <UnixDatagram> (1.22.0 при написании этой строки). c.downcast_ref::<UnixDatagram>().unwrap().shutdown(Shutdown::Both).unwrap();