Skip to content

Instantly share code, notes, and snippets.

@badboy
Created July 15, 2021 13:16
Show Gist options
  • Save badboy/52d01594ff3217445a089243a87592a6 to your computer and use it in GitHub Desktop.
Save badboy/52d01594ff3217445a089243a87592a6 to your computer and use it in GitHub Desktop.
[package]
name = "pingserver"
version = "0.1.0"
edition = "2018"
[dependencies]
tide = "0.16.0"
async-std = { version = "1.8.0", features = ["attributes"] }
serde = { version = "1.0.126", features = ["derive"] }
chrono = "0.4.19"
flate2 = "1.0.20"
serde_json = "1.0.64"
use std::io::prelude::*;
use std::io;
use std::path::Path;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use async_std::fs::File;
use async_std::prelude::*;
use tide::{Request, Server};
use tide::prelude::*;
use chrono::prelude::*;
use flate2::read::GzDecoder;
#[derive(Debug, Serialize)]
struct Header<'a> {
appid: &'a str,
ping: &'a str,
docid: &'a str,
submission: &'a str,
}
#[derive(Clone)]
pub struct State {
ping_count: Arc<AtomicUsize>
}
#[async_std::main]
async fn main() -> tide::Result<()> {
tide::log::start();
let mut app = Server::with_state(State {
ping_count: Arc::new(AtomicUsize::new(0))
});
app.at("/submit/:appid/:ping/:version/:docid").post(ping);
app.listen("127.0.0.1:6114").await?;
Ok(())
}
fn decompress(bytes: &[u8]) -> io::Result<String> {
let mut gz = GzDecoder::new(bytes);
let mut s = String::with_capacity(bytes.len());
gz.read_to_string(&mut s).map(|_| s)
}
async fn ping(mut req: Request<State>) -> tide::Result {
let now: DateTime<Local> = Local::now();
let appid = req.param("appid")?;
let ping = req.param("ping")?;
let docid = req.param("docid")?;
let submission = now.to_rfc3339();
let header = Header {
appid,
ping,
docid: docid,
submission: &submission,
};
let header = serde_json::to_string_pretty(&header).unwrap();
let state = req.state();
let id = state.ping_count.fetch_add(1, Ordering::SeqCst);
let file = format!("{:03}-{}-{}.json", id, ping, docid);
let path = Path::new("pings").join(file);
let body: Vec<u8> = req.body_bytes().await.unwrap();
let payload = decompress(&body)?;
let payload: serde_json::Value = serde_json::from_str(&payload).unwrap();
let payload = serde_json::to_string_pretty(&payload).unwrap();
let mut file = File::create(path).await?;
file.write_all(header.as_bytes()).await?;
file.write_all(b"\n").await?;
file.write_all(payload.as_bytes()).await?;
file.write_all(b"\n").await?;
Ok("OK".into())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment