|
|
@ -2,10 +2,11 @@ mod errors;
|
|
|
|
mod http;
|
|
|
|
mod http;
|
|
|
|
mod post;
|
|
|
|
mod post;
|
|
|
|
|
|
|
|
|
|
|
|
use crate::errors::{RequestError, HandlingError, InternalError};
|
|
|
|
use crate::errors::{HandlingError, InternalError, RequestError};
|
|
|
|
use crate::http::{Request, Response, Status};
|
|
|
|
use crate::http::{Request, Response, Status};
|
|
|
|
use crate::post::{Post, Thread};
|
|
|
|
use crate::post::{Post, Thread};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::error::Error;
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
use std::net::{SocketAddr, TcpListener, TcpStream};
|
|
|
|
use std::net::{SocketAddr, TcpListener, TcpStream};
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::path::PathBuf;
|
|
|
@ -16,10 +17,10 @@ use std::sync::{Arc, Mutex, MutexGuard};
|
|
|
|
use bincode::{deserialize, serialize};
|
|
|
|
use bincode::{deserialize, serialize};
|
|
|
|
use cached::proc_macro::cached;
|
|
|
|
use cached::proc_macro::cached;
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
|
|
|
use log::*;
|
|
|
|
use simplelog::*;
|
|
|
|
use simplelog::*;
|
|
|
|
use structopt::StructOpt;
|
|
|
|
use structopt::StructOpt;
|
|
|
|
use threadpool::ThreadPool;
|
|
|
|
use threadpool::ThreadPool;
|
|
|
|
use log::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// statically linked index and favicon
|
|
|
|
// statically linked index and favicon
|
|
|
|
const INDEX: &'static str = include_str!("www/index.html");
|
|
|
|
const INDEX: &'static str = include_str!("www/index.html");
|
|
|
@ -66,16 +67,14 @@ impl State {
|
|
|
|
fn handle(request: &str, state: Arc<Mutex<State>>) -> Response {
|
|
|
|
fn handle(request: &str, state: Arc<Mutex<State>>) -> Response {
|
|
|
|
let request = match request.parse::<Request>() {
|
|
|
|
let request = match request.parse::<Request>() {
|
|
|
|
Ok(s) => s,
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
Err(e) => return Response::new(Status::BadRequest, vec![], e.to_string()),
|
|
|
|
return Response::new(Status::BadRequest, vec![], "".to_string())
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let state = state.lock().unwrap();
|
|
|
|
let state = state.lock().unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
match request.method.as_str() {
|
|
|
|
match request.method.as_str() {
|
|
|
|
"GET" => match get(&request.uri, state) {
|
|
|
|
"GET" => match get(&request.uri, state) {
|
|
|
|
Ok(s) => s,
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => Response::new(Status::NotFound, vec![], "".to_string()),
|
|
|
|
Err(e) => Response::new(Status::NotFound, vec![], e.to_string()),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"POST" => post(request, state),
|
|
|
|
"POST" => post(request, state),
|
|
|
|
// check admin hash
|
|
|
|
// check admin hash
|
|
|
@ -114,9 +113,12 @@ fn get(path: &str, state: MutexGuard<State>) -> Result<Response, HandlingError>
|
|
|
|
let content = content(
|
|
|
|
let content = content(
|
|
|
|
s,
|
|
|
|
s,
|
|
|
|
&deserialize::<Thread>(
|
|
|
|
&deserialize::<Thread>(
|
|
|
|
&state.db.get(&s.as_bytes())
|
|
|
|
&state
|
|
|
|
|
|
|
|
.db
|
|
|
|
|
|
|
|
.get(&s.as_bytes())
|
|
|
|
.map_err(|_| HandlingError::ServerError(InternalError::DatabaseReadError))?
|
|
|
|
.map_err(|_| HandlingError::ServerError(InternalError::DatabaseReadError))?
|
|
|
|
.ok_or(HandlingError::ClientError(RequestError::NotFound))?)
|
|
|
|
.ok_or(HandlingError::ClientError(RequestError::NotFound))?,
|
|
|
|
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
.unwrap()
|
|
|
|
.to_string(),
|
|
|
|
.to_string(),
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -141,7 +143,8 @@ fn post(request: Request, mut state: MutexGuard<State>) -> Response {
|
|
|
|
|
|
|
|
|
|
|
|
state
|
|
|
|
state
|
|
|
|
.db
|
|
|
|
.db
|
|
|
|
.insert(id.to_ne_bytes(), serialize(&thread).unwrap());
|
|
|
|
.insert(id.to_ne_bytes(), serialize(&thread).unwrap())
|
|
|
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
Response::new(Status::Ok, vec![], String::from(""))
|
|
|
|
Response::new(Status::Ok, vec![], String::from(""))
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -168,8 +171,12 @@ fn main() {
|
|
|
|
let pool = ThreadPool::new(num_cpus::get());
|
|
|
|
let pool = ThreadPool::new(num_cpus::get());
|
|
|
|
// setup logger
|
|
|
|
// setup logger
|
|
|
|
TermLogger::init(
|
|
|
|
TermLogger::init(
|
|
|
|
LevelFilter::Warn, Config::default(), TerminalMode::Mixed, ColorChoice::Auto
|
|
|
|
LevelFilter::Warn,
|
|
|
|
).unwrap();
|
|
|
|
Config::default(),
|
|
|
|
|
|
|
|
TerminalMode::Mixed,
|
|
|
|
|
|
|
|
ColorChoice::Auto,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.unwrap();
|
|
|
|
// open database
|
|
|
|
// open database
|
|
|
|
let state = Arc::new(Mutex::new(State {
|
|
|
|
let state = Arc::new(Mutex::new(State {
|
|
|
|
db: sled::open(&OPT.database).unwrap(),
|
|
|
|
db: sled::open(&OPT.database).unwrap(),
|
|
|
|