mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-04 08:30:39 +00:00
memcached
This commit is contained in:
@@ -7,14 +7,19 @@ pub struct Note {
|
||||
pub contents: String,
|
||||
pub password: bool,
|
||||
pub views: Option<u8>,
|
||||
pub expiration: Option<u16>,
|
||||
pub expiration: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct PubNote {
|
||||
pub struct NoteInfo {
|
||||
pub password: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct NotePublic {
|
||||
pub contents: String,
|
||||
}
|
||||
|
||||
pub fn generate_id() -> String {
|
||||
let mut id: [u8; 64] = [0; 64];
|
||||
let sr = ring::rand::SystemRandom::new();
|
||||
|
@@ -1,24 +1,40 @@
|
||||
use actix_web::{delete, get, post, web, HttpResponse, Responder};
|
||||
use memcache;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use crate::note::{generate_id, Note, PubNote};
|
||||
use crate::note::{generate_id, Note, NoteInfo, NotePublic};
|
||||
|
||||
fn now() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref RAM: Mutex<HashMap<String, Note>> = {
|
||||
let mut m = HashMap::new();
|
||||
m.insert(
|
||||
"test".to_string(),
|
||||
Note {
|
||||
contents: "some stuff".to_string(),
|
||||
password: false,
|
||||
views: Some(1),
|
||||
expiration: Some(100),
|
||||
},
|
||||
);
|
||||
return Mutex::new(m);
|
||||
};
|
||||
static ref CLIENT: memcache::Client =
|
||||
memcache::connect("memcache://127.0.0.1:11211?timeout=10&tcp_nodelay=true").unwrap();
|
||||
}
|
||||
|
||||
fn set(id: &String, note: &Note) {
|
||||
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
||||
CLIENT.set(id, serialized, 0).unwrap();
|
||||
}
|
||||
|
||||
fn get(id: &String) -> Option<Note> {
|
||||
let value: Option<String> = CLIENT.get(&id).unwrap();
|
||||
match value {
|
||||
None => return None,
|
||||
Some(s) => {
|
||||
let deserialize: Note = serde_json::from_str(&s).unwrap();
|
||||
return Some(deserialize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn del(id: &String) {
|
||||
CLIENT.delete(id).unwrap();
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -28,25 +44,18 @@ struct NotePath {
|
||||
|
||||
#[get("/notes/{id}")]
|
||||
async fn one(path: web::Path<NotePath>) -> impl Responder {
|
||||
let ram = RAM.lock().unwrap();
|
||||
let p = path.into_inner();
|
||||
let note = ram.get(&p.id);
|
||||
let note = get(&p.id);
|
||||
match note {
|
||||
None => return HttpResponse::NotFound().finish(),
|
||||
Some(note) => {
|
||||
return HttpResponse::Ok().json(PubNote {
|
||||
return HttpResponse::Ok().json(NoteInfo {
|
||||
password: note.password,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/notes/")]
|
||||
async fn all() -> impl Responder {
|
||||
let values: Vec<Note> = RAM.lock().unwrap().values().cloned().collect();
|
||||
return HttpResponse::Ok().json(values);
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct CreateResponse {
|
||||
id: String,
|
||||
@@ -54,37 +63,68 @@ struct CreateResponse {
|
||||
|
||||
#[post("/notes/")]
|
||||
async fn create(note: web::Json<Note>) -> impl Responder {
|
||||
let n = note.into_inner();
|
||||
let mut n = note.into_inner();
|
||||
let id = generate_id();
|
||||
RAM.lock().unwrap().insert(id.clone(), n.clone());
|
||||
let bad_req = HttpResponse::BadRequest().finish();
|
||||
if n.views == None && n.expiration == None {
|
||||
return bad_req;
|
||||
}
|
||||
match n.views {
|
||||
Some(v) => {
|
||||
if v > 100 {
|
||||
return bad_req;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match n.expiration {
|
||||
Some(e) => {
|
||||
if e > 360 {
|
||||
return bad_req;
|
||||
}
|
||||
n.expiration = Some(now() + (e * 60))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
set(&id.clone(), &n.clone());
|
||||
return HttpResponse::Ok().json(CreateResponse { id: id });
|
||||
}
|
||||
|
||||
#[delete("/notes/{id}")]
|
||||
async fn delete(path: web::Path<NotePath>) -> impl Responder {
|
||||
let mut ram = RAM.lock().unwrap();
|
||||
let p = path.into_inner();
|
||||
let note = ram.get(&p.id);
|
||||
let note = get(&p.id);
|
||||
match note {
|
||||
None => return HttpResponse::NotFound().finish(),
|
||||
Some(note) => {
|
||||
let mut changed = note.clone();
|
||||
if changed.views == None && changed.expiration == None {
|
||||
return HttpResponse::BadRequest().finish();
|
||||
} else {
|
||||
match changed.views {
|
||||
Some(v) => {
|
||||
changed.views = Some(v - 1);
|
||||
if v <= 1 {
|
||||
ram.remove(&p.id);
|
||||
} else {
|
||||
ram.insert(p.id, changed.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return HttpResponse::Ok().json(changed);
|
||||
}
|
||||
match changed.views {
|
||||
Some(v) => {
|
||||
changed.views = Some(v - 1);
|
||||
let id = p.id.clone();
|
||||
if v <= 1 {
|
||||
del(&id);
|
||||
} else {
|
||||
set(&id, &changed.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match changed.expiration {
|
||||
Some(e) => {
|
||||
if e > now() {
|
||||
del(&p.id.clone());
|
||||
return HttpResponse::BadRequest().finish();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return HttpResponse::Ok().json(NotePublic {
|
||||
contents: changed.contents,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,5 +133,4 @@ pub fn init(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(create);
|
||||
cfg.service(delete);
|
||||
cfg.service(one);
|
||||
cfg.service(all);
|
||||
}
|
||||
|
Reference in New Issue
Block a user