Complete control Web APIs

This commit is contained in:
DaLaw2 2024-12-03 14:32:56 +08:00
parent 084da32b41
commit f97168904c
9 changed files with 413 additions and 27 deletions

View File

@ -67,7 +67,7 @@ fn ipv4_http_service_violation(
}
match IPV4_HTTP_SERVICE.get_ptr_mut(destination) {
Some(allow_method) => match get_http_request_method(start, end, offset) {
Some(http_method) => unsafe { *allow_method & http_method == 0 },
Some(http_method) => *allow_method & http_method == 0,
None => true,
},
None => false,
@ -96,7 +96,7 @@ fn ipv6_http_service_violation(
}
match IPV6_HTTP_SERVICE.get_ptr_mut(destination) {
Some(allow_method) => match get_http_request_method(start, end, offset) {
Some(http_method) => unsafe { *allow_method & http_method == 0 },
Some(http_method) => *allow_method & http_method == 0,
None => true,
},
None => false,

View File

@ -3,13 +3,13 @@ use crate::model::http_method::HttpMethod;
use crate::utils::ip_address::convert_ports_to_vec;
use crate::utils::log_entry::ebpf::EbpfEntry;
use crate::utils::log_entry::system::SystemEntry;
use aya::maps::{Array as AyaArray, HashMap as AyaHashMap, MapData, MapError};
use aya::maps::{Array as AyaArray, HashMap as AyaHashMap, MapData};
use net_guardia_common::model::http_method::EbpfHttpMethod;
use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6, IPv4, IPv6, Port};
use net_guardia_common::model::placeholder::PlaceHolder;
use net_guardia_common::MAX_RULES_PORT;
use std::collections::HashMap as StdHashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::sync::OnceLock;
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use tracing::{error, info};
@ -36,7 +36,7 @@ impl Control {
pub async fn initialize() -> anyhow::Result<()> {
info!("{}", SystemEntry::Initializing);
let mut system = System::instance_mut().await;
let mut ebpf = &mut system.ebpf;
let ebpf = &mut system.ebpf;
let mut control = Control {
ipv4_black_list: AyaHashMap::try_from(ebpf.take_map("IPV4_BLACKLIST").unwrap())?,
ipv6_black_list: AyaHashMap::try_from(ebpf.take_map("IPV6_BLACKLIST").unwrap())?,
@ -108,7 +108,7 @@ impl Control {
let ip: u32 = (*address.ip()).into();
let port = address.port();
let mut control = Control::instance_mut().await;
let (mut ports, index) = if let Ok(mut ports) = control.ipv4_black_list.get(&ip, 0) {
let (mut ports, index) = if let Ok(ports) = control.ipv4_black_list.get(&ip, 0) {
match ports.iter().position(|&x| x == 0) {
Some(index) => (ports, index),
None => Err(EbpfEntry::RuleReachLimit)?,
@ -128,7 +128,7 @@ impl Control {
let ip: u128 = (*address.ip()).into();
let port = address.port();
let mut control = Control::instance_mut().await;
let (mut ports, index) = if let Ok(mut ports) = control.ipv6_black_list.get(&ip, 0) {
let (mut ports, index) = if let Ok(ports) = control.ipv6_black_list.get(&ip, 0) {
match ports.iter().position(|&x| x == 0) {
Some(index) => (ports, index),
None => Err(EbpfEntry::RuleReachLimit)?,
@ -210,7 +210,7 @@ impl Control {
}
Ok(())
} else {
Err(EbpfEntry::IpDoesNotExist)?;
Err(EbpfEntry::IpDoesNotExist)?
}
}
@ -356,6 +356,74 @@ impl Control {
Ok(())
}
pub async fn get_ipv4_ssh_service() -> Vec<SocketAddrV4> {
let control = Control::instance().await;
control
.ipv4_ssh_service
.keys()
.filter_map(Result::ok)
.map(|key| SocketAddrV4::new(Ipv4Addr::from(key[0]), key[1] as u16))
.collect()
}
pub async fn get_ipv6_ssh_service() -> Vec<SocketAddrV6> {
let control = Control::instance().await;
control
.ipv6_ssh_service
.keys()
.filter_map(Result::ok)
.map(|key| SocketAddrV6::new(Ipv6Addr::from(key[0]), key[1] as u16, 0, 0))
.collect()
}
pub async fn add_ipv4_ssh_service(address: SocketAddrV4) -> anyhow::Result<()> {
let ip: u32 = (*address.ip()).into();
let port = address.port();
let addr_port = [ip, port as u32];
let mut control = Control::instance_mut().await;
control
.ipv4_ssh_service
.insert(&addr_port, 0_u8, 0)
.map_err(|_| EbpfEntry::RuleReachLimit)?;
Ok(())
}
pub async fn add_ipv6_ssh_service(address: SocketAddrV6) -> anyhow::Result<()> {
let ip: u128 = (*address.ip()).into();
let port = address.port();
let addr_port = [ip, port as u128];
let mut control = Control::instance_mut().await;
control
.ipv6_ssh_service
.insert(&addr_port, 0_u8, 0)
.map_err(|_| EbpfEntry::RuleReachLimit)?;
Ok(())
}
pub async fn remove_ipv4_ssh_service(address: SocketAddrV4) -> anyhow::Result<()> {
let ip: u32 = (*address.ip()).into();
let port = address.port();
let addr_port = [ip, port as u32];
let mut control = Control::instance_mut().await;
control
.ipv4_ssh_service
.remove(&addr_port)
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
pub async fn remove_ipv6_ssh_service(address: SocketAddrV6) -> anyhow::Result<()> {
let ip: u128 = (*address.ip()).into();
let port = address.port();
let addr_port = [ip, port as u128];
let mut control = Control::instance_mut().await;
control
.ipv6_ssh_service
.remove(&addr_port)
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
pub async fn get_ipv4_ssh_white_list() -> Vec<Ipv4Addr> {
let control = Control::instance().await;
control
@ -402,7 +470,7 @@ impl Control {
control
.ipv4_ssh_white_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
@ -412,7 +480,7 @@ impl Control {
control
.ipv6_ssh_white_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
@ -442,7 +510,7 @@ impl Control {
control
.ipv4_ssh_black_list
.insert(ip, 0_u8, 0)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::RuleReachLimit)?;
Ok(())
}
@ -452,27 +520,27 @@ impl Control {
control
.ipv6_ssh_black_list
.insert(ip, 0_u8, 0)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::RuleReachLimit)?;
Ok(())
}
pub async fn remove_ipv6_ssh_black_list(ip: Ipv4Addr) -> anyhow::Result<()> {
pub async fn remove_ipv4_ssh_black_list(ip: Ipv4Addr) -> anyhow::Result<()> {
let ip: u32 = ip.into();
let mut control = Control::instance_mut().await;
control
.ipv4_ssh_black_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
pub async fn remove_ipv4_ssh_black_list(ip: Ipv6Addr) -> anyhow::Result<()> {
pub async fn remove_ipv6_ssh_black_list(ip: Ipv6Addr) -> anyhow::Result<()> {
let ip: u128 = ip.into();
let mut control = Control::instance_mut().await;
control
.ipv6_ssh_black_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
@ -502,7 +570,7 @@ impl Control {
control
.ipv4_scanner_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
@ -512,7 +580,7 @@ impl Control {
control
.ipv6_scanner_list
.remove(&ip)
.map_err(EbpfEntry::from)?;
.map_err(|_| EbpfEntry::IpDoesNotExist)?;
Ok(())
}
}

View File

@ -34,7 +34,7 @@ impl Monitor {
pub async fn initialize() -> anyhow::Result<()> {
info!("{}", SystemEntry::Initializing);
let mut system = System::instance_mut().await;
let mut ebpf = &mut system.ebpf;
let ebpf = &mut system.ebpf;
let monitor = Monitor {
terminate: false,
ipv4_src_1min: AyaHashMap::try_from(ebpf.take_map("IPV4_SRC_1MIN").unwrap())?,

View File

@ -3,7 +3,7 @@ use crate::core::monitor::Monitor;
use crate::utils::log_entry::ebpf::EbpfEntry;
use crate::utils::log_entry::system::SystemEntry;
use crate::utils::logging::Logging;
use crate::web::api::{default, monitor};
use crate::web::api::{control, default, monitor};
use actix_web::web::route;
use actix_web::{App, HttpServer};
use anyhow::Context;
@ -12,6 +12,7 @@ use aya::Ebpf;
use std::sync::OnceLock;
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use tracing::{error, info, warn};
use crate::core::control::Control;
static SYSTEM: OnceLock<RwLock<System>> = OnceLock::new();
@ -26,6 +27,7 @@ impl System {
ConfigManager::initialization().await?;
System::ebpf_initialize().await?;
Monitor::initialize().await?;
Control::initialize().await?;
info!("{}", SystemEntry::InitializeComplete);
Ok(())
}
@ -64,6 +66,7 @@ impl System {
App::new()
.wrap(cors)
.service(monitor::initialize())
.service(control::initialize())
.default_service(route().to(default::default_route))
})
.bind(format!("0.0.0.0:{}", config.http_server_bind_port))?

View File

@ -1,4 +1,3 @@
use std::str::FromStr;
use serde::Deserialize;
#[derive(Deserialize, Debug, Copy, Clone)]

View File

@ -1,3 +0,0 @@
pub trait IntoString {
fn into_string(self) -> String;
}

View File

@ -1,4 +1,3 @@
use aya::maps::MapError;
use thiserror::Error;
#[derive(Error, Debug)]

View File

@ -1,5 +1,5 @@
use tokio::fs;
use tracing::{info, Level};
use tracing::Level;
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::filter::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;

View File

@ -1,7 +1,327 @@
use actix_web::{web, Scope};
use crate::core::control::Control;
use crate::model::http_method::HttpMethod;
use actix_web::{delete, get, post, put, web, HttpResponse, Responder, Scope};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
pub fn initialize() -> Scope {
web::scope("/control")
.service(get_ipv4_black_list)
.service(get_ipv6_black_list)
.service(add_ipv4_black_list)
.service(add_ipv6_black_list)
.service(remove_ipv4_black_list)
.service(remove_ipv6_black_list)
.service(get_ipv4_http_service)
.service(get_ipv6_http_service)
.service(add_ipv4_http_service)
.service(add_ipv6_http_service)
.service(remove_ipv4_http_service)
.service(remove_ipv6_http_service)
.service(is_ssh_white_list_enable)
.service(enable_ssh_white_list)
.service(disable_ssh_white_list)
.service(get_ipv4_ssh_service)
.service(get_ipv6_ssh_service)
.service(add_ipv4_ssh_service)
.service(add_ipv6_ssh_service)
.service(remove_ipv4_ssh_service)
.service(remove_ipv6_ssh_service)
.service(get_ipv4_ssh_white_list)
.service(get_ipv6_ssh_white_list)
.service(add_ipv4_ssh_white_list)
.service(add_ipv6_ssh_white_list)
.service(remove_ipv4_ssh_white_list)
.service(remove_ipv6_ssh_white_list)
.service(get_ipv4_ssh_black_list)
.service(get_ipv6_ssh_black_list)
.service(add_ipv4_ssh_black_list)
.service(add_ipv6_ssh_black_list)
.service(remove_ipv4_ssh_black_list)
.service(remove_ipv6_ssh_black_list)
.service(get_ipv4_scanner_list)
.service(get_ipv6_scanner_list)
.service(remove_ipv4_scanner_list)
.service(remove_ipv6_scanner_list)
}
#[get("/ipv4/black_list")]
async fn get_ipv4_black_list() -> impl Responder {
let list = Control::get_ipv4_black_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/black_list")]
async fn get_ipv6_black_list() -> impl Responder {
let list = Control::get_ipv6_black_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[put("/ipv4/black_list")]
async fn add_ipv4_black_list(ip_addr: web::Json<SocketAddrV4>) -> impl Responder {
match Control::add_ipv4_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[put("/ipv6/black_list")]
async fn add_ipv6_black_list(ip_addr: web::Json<SocketAddrV6>) -> impl Responder {
match Control::add_ipv6_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv4/black_list")]
async fn remove_ipv4_black_list(ip_addr: web::Json<SocketAddrV4>) -> impl Responder {
match Control::remove_ipv4_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/black_list")]
async fn remove_ipv6_black_list(ip_addr: web::Json<SocketAddrV6>) -> impl Responder {
match Control::remove_ipv6_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ipv4/http_service")]
async fn get_ipv4_http_service() -> impl Responder {
let list = Control::get_ipv4_http_service().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/http_service")]
async fn get_ipv6_http_service() -> impl Responder {
let list = Control::get_ipv6_http_service().await;
HttpResponse::Ok().json(web::Json(list))
}
#[put("/ipv4/http_service")]
async fn add_ipv4_http_service(
payload: web::Json<(SocketAddrV4, Vec<HttpMethod>)>,
) -> impl Responder {
let (addr, methods) = payload.into_inner();
match Control::add_ipv4_http_service(addr, methods).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[put("/ipv6/http_service")]
async fn add_ipv6_http_service(
payload: web::Json<(SocketAddrV6, Vec<HttpMethod>)>,
) -> impl Responder {
let (addr, methods) = payload.into_inner();
match Control::add_ipv6_http_service(addr, methods).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv4/http_service")]
async fn remove_ipv4_http_service(
payload: web::Json<(SocketAddrV4, Vec<HttpMethod>)>,
) -> impl Responder {
let (addr, methods) = payload.into_inner();
match Control::remove_ipv4_http_service(addr, methods).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/http_service")]
async fn remove_ipv6_http_service(
payload: web::Json<(SocketAddrV6, Vec<HttpMethod>)>,
) -> impl Responder {
let (addr, methods) = payload.into_inner();
match Control::remove_ipv6_http_service(addr, methods).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ssh_white_list")]
async fn is_ssh_white_list_enable() -> impl Responder {
let enabled = Control::is_ssh_white_list_enable().await;
HttpResponse::Ok().json(enabled)
}
#[post("/ssh_white_list/enable")]
async fn enable_ssh_white_list() -> impl Responder {
match Control::enable_ssh_white_list().await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[post("/ssh_white_list/disable")]
async fn disable_ssh_white_list() -> impl Responder {
match Control::disable_ssh_white_list().await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ipv4/ssh_service")]
async fn get_ipv4_ssh_service() -> impl Responder {
let list = Control::get_ipv4_ssh_service().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/ssh_service")]
async fn get_ipv6_ssh_service() -> impl Responder {
let list = Control::get_ipv6_ssh_service().await;
HttpResponse::Ok().json(web::Json(list))
}
#[put("/ipv4/ssh_service")]
async fn add_ipv4_ssh_service(ip_addr: web::Json<SocketAddrV4>) -> impl Responder {
match Control::add_ipv4_ssh_service(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[put("/ipv6/ssh_service")]
async fn add_ipv6_ssh_service(ip_addr: web::Json<SocketAddrV6>) -> impl Responder {
match Control::add_ipv6_ssh_service(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv4/ssh_service")]
async fn remove_ipv4_ssh_service(ip_addr: web::Json<SocketAddrV4>) -> impl Responder {
match Control::remove_ipv4_ssh_service(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/ssh_service")]
async fn remove_ipv6_ssh_service(ip_addr: web::Json<SocketAddrV6>) -> impl Responder {
match Control::remove_ipv6_ssh_service(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ipv4/ssh_white_list")]
async fn get_ipv4_ssh_white_list() -> impl Responder {
let list = Control::get_ipv4_ssh_white_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/ssh_white_list")]
async fn get_ipv6_ssh_white_list() -> impl Responder {
let list = Control::get_ipv6_ssh_white_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[put("/ipv4/ssh_white_list")]
async fn add_ipv4_ssh_white_list(ip_addr: web::Json<Ipv4Addr>) -> impl Responder {
match Control::add_ipv4_ssh_white_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[put("/ipv6/ssh_white_list")]
async fn add_ipv6_ssh_white_list(ip_addr: web::Json<Ipv6Addr>) -> impl Responder {
match Control::add_ipv6_ssh_white_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv4/ssh_white_list")]
async fn remove_ipv4_ssh_white_list(ip_addr: web::Json<Ipv4Addr>) -> impl Responder {
match Control::remove_ipv4_ssh_white_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/ssh_white_list")]
async fn remove_ipv6_ssh_white_list(ip_addr: web::Json<Ipv6Addr>) -> impl Responder {
match Control::remove_ipv6_ssh_white_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ipv4/ssh_black_list")]
async fn get_ipv4_ssh_black_list() -> impl Responder {
let list = Control::get_ipv4_ssh_black_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/ssh_black_list")]
async fn get_ipv6_ssh_black_list() -> impl Responder {
let list = Control::get_ipv6_ssh_black_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[put("/ipv4/ssh_black_list")]
async fn add_ipv4_ssh_black_list(ip_addr: web::Json<Ipv4Addr>) -> impl Responder {
match Control::add_ipv4_ssh_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[put("/ipv6/ssh_black_list")]
async fn add_ipv6_ssh_black_list(ip_addr: web::Json<Ipv6Addr>) -> impl Responder {
match Control::add_ipv6_ssh_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv4/ssh_black_list")]
async fn remove_ipv4_ssh_black_list(ip_addr: web::Json<Ipv4Addr>) -> impl Responder {
match Control::remove_ipv4_ssh_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/ssh_black_list")]
async fn remove_ipv6_ssh_black_list(ip_addr: web::Json<Ipv6Addr>) -> impl Responder {
match Control::remove_ipv6_ssh_black_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[get("/ipv4/scanner_list")]
async fn get_ipv4_scanner_list() -> impl Responder {
let list = Control::get_ipv4_scanner_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[get("/ipv6/scanner_list")]
async fn get_ipv6_scanner_list() -> impl Responder {
let list = Control::get_ipv6_scanner_list().await;
HttpResponse::Ok().json(web::Json(list))
}
#[delete("/ipv4/scanner_list")]
async fn remove_ipv4_scanner_list(ip_addr: web::Json<Ipv4Addr>) -> impl Responder {
match Control::remove_ipv4_scanner_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[delete("/ipv6/scanner_list")]
async fn remove_ipv6_scanner_list(ip_addr: web::Json<Ipv6Addr>) -> impl Responder {
match Control::remove_ipv6_scanner_list(ip_addr.into_inner()).await {
Ok(_) => HttpResponse::Ok().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}