use mini_async_http::aioserver::AIOServer;
use mini_async_http::http::Headers;
use mini_async_http::http::Method;
use mini_async_http::http::Version;
use mini_async_http::request::{Request, RequestBuilder};
use mini_async_http::response::{Response, ResponseBuilder};
use std::sync::Mutex;
extern crate lazy_static;
use lazy_static::lazy_static;
pub type Handler = Box<dyn Send + Sync + 'static + Fn(&Request) -> Response>;
pub struct ServerConfig {
pub addr: String,
pub http_addr: String,
}
impl Clone for ServerConfig {
fn clone(&self) -> ServerConfig {
ServerConfig {
addr: self.addr.clone(),
http_addr: self.http_addr.clone(),
}
}
}
pub struct ServerGenerator {
port: Mutex<u32>,
}
lazy_static! {
static ref GENERATOR: ServerGenerator = {
ServerGenerator {
port: Mutex::from(12343),
}
};
}
impl ServerGenerator {
pub fn server(&self) -> (AIOServer<Handler>, ServerConfig) {
let portstr = self.incr().to_string();
let server = server(portstr.as_str());
let config = ServerConfig {
addr: addr(portstr.as_str()),
http_addr: http_addr(portstr.as_str()),
};
(server, config)
}
fn incr(&self) -> u32 {
let mut port = self.port.lock().unwrap();
let val = *port;
*port = *port + 1;
val
}
}
pub fn handler_basic(request: &Request) -> Response {
let body = request.method().as_str().to_string().as_bytes().to_vec();
let builder = ResponseBuilder::new()
.code(200)
.reason(String::from("OK"))
.version(Version::HTTP11)
.body(&body)
.header("Content-Type", "text/plain")
.header(
"Content-Length",
request.method().as_str().len().to_string().as_str(),
);
let response = builder.build().unwrap();
return response;
}
fn server(port: &str) -> AIOServer<Handler> {
let addr = format!("127.0.0.1:{}", port);
AIOServer::new(1, addr.as_str(), Box::new(handler_basic))
}
fn addr(port: &str) -> String {
format!("0.0.0.0:{}", port)
}
fn http_addr(port: &str) -> String {
format!("http://{}", addr(port))
}
pub fn request() -> Request {
let _body = String::from("TEST BODY").as_bytes().to_vec();
let mut headers = Headers::new();
headers.set_header(&String::from("content-length"), &String::from("9"));
RequestBuilder::new()
.method(Method::GET)
.path(String::from("/"))
.version(Version::HTTP11)
.headers(headers)
.body(b"TEST BODY")
.build()
.unwrap()
}
pub fn run_test<T>(test: T) -> ()
where
T: FnOnce(ServerConfig) -> () + std::panic::UnwindSafe,
{
let (server, config) = GENERATOR.server();
let server = std::sync::Arc::from(server);
let clone = server.clone();
std::thread::spawn(move || {
server.start();
});
clone.ready();
let result = std::panic::catch_unwind(|| test(config));
clone.shutdown();
assert!(result.is_ok())
}