dcache/src/network/api.rs

158 lines
4.5 KiB
Rust

/*
* mCaptcha - A proof of work based DoS protection system
* Copyright © 2023 Aravinth Manivannan <realravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use actix_web::get;
use actix_web::post;
use actix_web::web;
use actix_web::web::Data;
use actix_web::Responder;
use libmcaptcha::cache::messages::{CachedPoWConfig, RetrivePoW, VerifyCaptchaResult};
use libmcaptcha::master::messages::GetInternalData;
use serde::Deserialize;
use serde::Serialize;
use web::Json;
use crate::app::DcacheApp;
use crate::store::DcacheRequest;
#[post("/write")]
pub async fn write(
app: Data<DcacheApp>,
req: Json<DcacheRequest>,
) -> actix_web::Result<impl Responder> {
let response = app.raft.client_write(req.0).await;
Ok(Json(response))
}
#[get("/state")]
pub async fn state(app: Data<DcacheApp>) -> actix_web::Result<impl Responder> {
let sm = app.store.state_machine.read().await;
let resp = sm
.data
.master
.send(GetInternalData)
.await
.unwrap()
.await
.unwrap()
.unwrap();
Ok(Json(resp))
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ReadRequest {
RetrivePoW(RetrivePoW), //Reader
VerifyCaptchaResult(VerifyCaptchaResult), //Reader
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum ReadResponse {
VerifyCaptchaResult(bool),
RetrivePoW(Option<CachedPoWConfig>),
}
#[post("/read")]
pub async fn read(
app: Data<DcacheApp>,
req: Json<ReadRequest>,
) -> actix_web::Result<impl Responder> {
let sm = app.store.state_machine.read().await;
let req = req.into_inner();
let res = match req {
ReadRequest::RetrivePoW(msg) => {
let cache_res = sm
.data
.cache
.send(msg.clone())
.await
.unwrap()
.await
.unwrap()
.unwrap();
ReadResponse::RetrivePoW(cache_res)
}
ReadRequest::VerifyCaptchaResult(msg) => {
let cache_res = sm
.data
.cache
.send(msg.clone())
.await
.unwrap()
.await
.unwrap()
.unwrap();
ReadResponse::VerifyCaptchaResult(cache_res)
}
};
Ok(Json(res))
}
#[post("/pipeline/read")]
pub async fn pipeline_read(
app: Data<DcacheApp>,
requests: Json<Vec<ReadRequest>>,
) -> actix_web::Result<impl Responder> {
let requests = requests.into_inner();
let mut responses = Vec::with_capacity(requests.len());
let sm = app.store.state_machine.read().await;
for request in requests {
let res = match request {
ReadRequest::RetrivePoW(msg) => {
let cache_res = sm
.data
.cache
.send(msg.clone())
.await
.unwrap()
.await
.unwrap()
.unwrap();
ReadResponse::RetrivePoW(cache_res)
}
ReadRequest::VerifyCaptchaResult(msg) => {
let cache_res = sm
.data
.cache
.send(msg.clone())
.await
.unwrap()
.await
.unwrap()
.unwrap();
ReadResponse::VerifyCaptchaResult(cache_res)
}
};
responses.push(res);
}
Ok(Json(responses))
}
#[post("/pipeline/write")]
pub async fn pipeline_write(
app: Data<DcacheApp>,
requests: Json<Vec<DcacheRequest>>,
) -> actix_web::Result<impl Responder> {
let mut responses = Vec::with_capacity(requests.len());
let mut requests = requests.into_inner();
for req in requests.drain(0..) {
responses.push(app.raft.client_write(req).await);
}
Ok(Json(responses))
}