1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-02 13:29:24 +00:00
actix-web/src/server/ssl/openssl.rs
2019-05-15 08:38:59 -07:00

100 lines
2.8 KiB
Rust

use std::net::{Shutdown, SocketAddr};
use std::rc::Rc;
use std::{io, time};
use actix_net::ssl;
use openssl::ssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_openssl::SslStream;
use extensions::Extensions;
use server::{IoStream, ServerFlags};
/// Support `SSL` connections via openssl package
///
/// `ssl` feature enables `OpensslAcceptor` type
pub struct OpensslAcceptor<T> {
_t: ssl::OpensslAcceptor<T>,
}
impl<T: AsyncRead + AsyncWrite> OpensslAcceptor<T> {
/// Create `OpensslAcceptor` with enabled `HTTP/2` and `HTTP1.1` support.
pub fn new(builder: SslAcceptorBuilder) -> io::Result<ssl::OpensslAcceptor<T>> {
OpensslAcceptor::with_flags(builder, ServerFlags::HTTP1 | ServerFlags::HTTP2)
}
/// Create `OpensslAcceptor` with custom server flags.
pub fn with_flags(
builder: SslAcceptorBuilder, flags: ServerFlags,
) -> io::Result<ssl::OpensslAcceptor<T>> {
let acceptor = openssl_acceptor_with_flags(builder, flags)?;
Ok(ssl::OpensslAcceptor::new(acceptor))
}
}
/// Configure `SslAcceptorBuilder` with custom server flags.
pub fn openssl_acceptor_with_flags(
mut builder: SslAcceptorBuilder, flags: ServerFlags,
) -> io::Result<SslAcceptor> {
let mut protos = Vec::new();
if flags.contains(ServerFlags::HTTP1) {
protos.extend(b"\x08http/1.1");
}
if flags.contains(ServerFlags::HTTP2) {
protos.extend(b"\x02h2");
builder.set_alpn_select_callback(|_, protos| {
const H2: &[u8] = b"\x02h2";
if protos.windows(3).any(|window| window == H2) {
Ok(b"h2")
} else {
Err(AlpnError::NOACK)
}
});
}
if !protos.is_empty() {
builder.set_alpn_protos(&protos)?;
}
Ok(builder.build())
}
impl<T: IoStream> IoStream for SslStream<T> {
#[inline]
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
let _ = self.get_mut().shutdown();
Ok(())
}
#[inline]
fn peer_addr(&self) -> Option<SocketAddr> {
self.get_ref().get_ref().peer_addr()
}
#[inline]
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
self.get_mut().get_mut().set_nodelay(nodelay)
}
#[inline]
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().get_mut().set_linger(dur)
}
#[inline]
fn set_keepalive(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
self.get_mut().get_mut().set_keepalive(dur)
}
fn extensions(&self) -> Option<Rc<Extensions>> {
if let Some(x509) = self.get_ref().ssl().peer_certificate() {
let mut extensions = Extensions::new();
extensions.insert(x509);
Some(Rc::new(extensions))
} else {
None
}
}
}