158 lines
4.5 KiB
Rust
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))
|
|
}
|