httpbis 0.6.1

Rust implementation of HTTP/2 protocol
Documentation
use std::net::SocketAddr;
use std::io;
use std::any::Any;

use tokio_core::reactor;
use tokio_core::net::TcpListener;
use tokio_core::net::TcpStream;

use futures::stream::Stream;
use futures::Future;

use server_conf::ServerConf;

use net2;

use socket::AnySocketAddr;
use socket::ToSocketListener;
use socket::ToTokioListener;
use socket::ToServerStream;
use socket::ToClientStream;
use socket::StreamItem;


impl ToSocketListener for SocketAddr {
    fn to_listener(&self, conf: &ServerConf) -> Box<ToTokioListener + Send> {
        Box::new(listener(self, conf).unwrap())
    }

    fn cleanup(&self) {}
}

#[cfg(unix)]
fn configure_tcp(tcp: &net2::TcpBuilder, conf: &ServerConf) -> io::Result<()> {
    use net2::unix::UnixTcpBuilderExt;
    if let Some(reuse_port) = conf.reuse_port {
        tcp.reuse_port(reuse_port)?;
    }
    Ok(())
}

#[cfg(windows)]
fn configure_tcp(_tcp: &net2::TcpBuilder, conf: &ServerConf) -> io::Result<()> {
    Ok(())
}

fn listener(
    addr: &SocketAddr,
    conf: &ServerConf)
        -> io::Result<::std::net::TcpListener>
{
    let listener = match *addr {
        SocketAddr::V4(_) => net2::TcpBuilder::new_v4()?,
        SocketAddr::V6(_) => net2::TcpBuilder::new_v6()?,
    };

    if let SocketAddr::V6(_) = *addr {
        // Assume only_v6 = false by default
        // Note: it is not default behavior for Rust
        let only_v6 = conf.only_v6.unwrap_or(false);
        listener.only_v6(only_v6)?;
    }

    configure_tcp(&listener, conf)?;
    listener.reuse_address(true)?;
    listener.bind(addr)?;
    let backlog = conf.backlog.unwrap_or(1024);
    listener.listen(backlog)
}

impl ToTokioListener for ::std::net::TcpListener {
    fn to_tokio_listener(self: Box<Self>, handle: &reactor::Handle) -> Box<ToServerStream> {
        let local_addr = self.local_addr().unwrap();
        Box::new(TcpListener::from_listener(*self, &local_addr, handle).unwrap())
    }

    fn local_addr(&self) -> io::Result<AnySocketAddr> {
        Ok(AnySocketAddr::Inet(self.local_addr().unwrap()))
    }
}

impl ToServerStream for TcpListener {
    fn incoming(self: Box<Self>)
        -> Box<Stream<Item=(Box<StreamItem>, Box<Any>), Error=io::Error>>
    {
        let stream = (*self).incoming().map(|(stream, addr)|
            (Box::new(stream) as Box<StreamItem>, Box::new(addr) as Box<Any>)
        );
        Box::new(stream)
    }
}

impl ToClientStream for SocketAddr {
    fn connect(&self, handle: &reactor::Handle)
        -> Box<Future<Item=Box<StreamItem>, Error=io::Error> + Send>
    {
        let stream = TcpStream::connect(self, &handle).map(|stream|
            Box::new(stream) as Box<StreamItem>
        );
        Box::new(stream)
    }
}

impl StreamItem for TcpStream {
    fn is_tcp(&self) -> bool {
        true
    }

    fn set_nodelay(&self, no_delay: bool) -> io::Result<()> {
        self.set_nodelay(no_delay)
    }
}