Skip to content

Instantly share code, notes, and snippets.

@goriunov
Created December 30, 2018 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goriunov/3f2553cffd7232f5dbb2f5535cac322f to your computer and use it in GitHub Desktop.
Save goriunov/3f2553cffd7232f5dbb2f5535cac322f to your computer and use it in GitHub Desktop.
use futures;
use futures::try_ready;
use tokio;
use tokio::prelude::*;
use tokio::net::TcpListener;
use std::sync::{Arc, Mutex};
pub fn run() {
let addr = "0.0.0.0:3000".parse().unwrap();
let listener = TcpListener::bind(&addr).expect("unable to bind TCP listener");
let mut myFns = FunctionsReturn::new(Box::new(|arr| {
Box::new(futures::future::ok(String::from("Hello world")))
}));
let myFns = Arc::new(myFns);
let server = listener
.incoming()
.map_err(|e| eprintln!("accept failed = {:?}", e))
.for_each(move |sock| {
// all logic
let (read, write) = sock.split();
let myFns = Arc::clone(&myFns);
let process = Reader::new(read)
.map_err(|e| println!("Error is: {}", e))
.fold(write, move |write, data| {
(myFns.case1Fn.as_ref())(data)
.and_then(|msg| {
println!("Message is {}", msg);
tokio::io::write_all(
write,
&"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!".as_bytes()[..],
)
.map_err(|e| println!("Error is: {}", e))
.map(|(w, _)| w)
})
})
.map(|_| ());
tokio::spawn(process)
});
tokio::run(server);
}
// different cases functions
type Func = Box<Fn(Vec<u8>) -> Box<Future<Item = String, Error = ()>> + Send + Sync>;
pub struct FunctionsReturn {
pub case1Fn: Func,
}
impl FunctionsReturn {
pub fn new(fnc: Func) -> FunctionsReturn {
FunctionsReturn {
case1Fn: fnc,
}
}
pub fn addCase1Fn(&mut self, func: Func) {
self.case1Fn = func;
}
}
// Create reader for http
pub struct Reader<S> {
sock: S,
buf: Vec<u8>,
}
impl<S: AsyncRead> Reader<S> {
pub fn new(sock: S) -> Reader<S> {
Reader {
sock,
buf: Vec::new(),
}
}
}
impl<S: AsyncRead> Stream for Reader<S> {
type Item = Vec<u8>;
type Error = std::io::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
// simple buf reader
loop {
let n = match self.sock.read_buf(&mut self.buf) {
Ok(Async::Ready(0)) => {
return Ok(Async::Ready(None));
}
Ok(Async::Ready(n)) => n,
Ok(Async::NotReady) => {
break;
}
Err(e) => {
println!("Error reading {}", e);
return Err(e);
}
};
}
if !self.buf.is_empty() {
return Ok(Async::Ready(Some(self.buf.drain(..).collect())));
}
Ok(Async::NotReady)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment