netopt 0.1.3

Provides options to work with tcp or ssl streams and has a choice in between.
use std::net::TcpStream;
use std::io;
use std::sync::Arc;
use std::path::Path;
use openssl::ssl::{self, SslMethod, SSL_VERIFY_NONE};
use openssl::x509::X509FileType;

pub type SslStream = ssl::SslStream<TcpStream>;
pub type SslError = ssl::error::SslError;

#[derive(Debug, Clone)]
pub struct SslContext {
    inner: Arc<ssl::SslContext>
}

impl Default for SslContext {
    fn default() -> SslContext {
        SslContext {
            inner: Arc::new(ssl::SslContext::new(SslMethod::Tlsv1_2).unwrap())
        }
    }
}

impl SslContext {
    pub fn new(context: ssl::SslContext) -> Self {
        SslContext {
            inner: Arc::new(context)
        }
    }

    pub fn with_cert_and_key<C, K>(cert: C, key: K) -> Result<SslContext, SslError>
    where C: AsRef<Path>, K: AsRef<Path> {
        let mut ctx = try!(ssl::SslContext::new(SslMethod::Sslv23));
        try!(ctx.set_cipher_list("DEFAULT"));
        try!(ctx.set_certificate_file(cert.as_ref(), X509FileType::PEM));
        try!(ctx.set_private_key_file(key.as_ref(), X509FileType::PEM));
        ctx.set_verify(SSL_VERIFY_NONE, None);
        Ok(SslContext { inner: Arc::new(ctx) })
    }

    pub fn accept(&self, stream: TcpStream) -> Result<SslStream, io::Error> {
        match ssl::SslStream::accept(&*self.inner, stream) {
            Ok(stream) => Ok(stream),
            Err(err) => Err(io::Error::new(io::ErrorKind::ConnectionAborted, err).into())
        }
    }

    pub fn connect(&self, stream: TcpStream) -> Result<SslStream, io::Error> {
        match ssl::SslStream::connect(&*self.inner, stream) {
            Ok(stream) => Ok(stream),
            Err(err) => Err(io::Error::new(io::ErrorKind::ConnectionAborted, err).into())
        }
    }
}