diff --git a/CHANGES.md b/CHANGES.md index e7812472c..760dbcc55 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,10 +1,15 @@ # Changes -## 0.3.3 (2018-01-xx) +## 0.3.3 (2018-01-25) * Stop processing any events after context stop -* Re-enable write back pressure for h1 connections +* Re-enable write back-pressure for h1 connections + +* Refactor HttpServer::start_ssl() method + +* Upgrade openssl to 0.10 + ## 0.3.2 (2018-01-21) diff --git a/Cargo.toml b/Cargo.toml index 371aad29b..46afb692c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "0.3.2" +version = "0.3.3" authors = ["Nikolay Kim "] description = "Actix web framework" readme = "README.md" @@ -71,15 +71,12 @@ native-tls = { version="0.1", optional = true } tokio-tls = { version="0.1", optional = true } # openssl -tokio-openssl = { version="0.1", optional = true } +openssl = { version="0.10", optional = true } +tokio-openssl = { version="0.2", optional = true } [dependencies.actix] version = "^0.4.5" -[dependencies.openssl] -version = "0.9" -optional = true - [dev-dependencies] env_logger = "0.5" reqwest = "0.8" @@ -93,7 +90,6 @@ version_check = "0.1" [profile.release] lto = true opt-level = 3 -# debug = true [workspace] members = [ diff --git a/examples/tls/Cargo.toml b/examples/tls/Cargo.toml index 024d7fc1d..4d227c7c3 100644 --- a/examples/tls/Cargo.toml +++ b/examples/tls/Cargo.toml @@ -12,3 +12,4 @@ path = "src/main.rs" env_logger = "0.5" actix = "^0.4.2" actix-web = { path = "../../", features=["alpn"] } +openssl = { version="0.10", features = ["v110"] } diff --git a/examples/tls/cert.pem b/examples/tls/cert.pem new file mode 100644 index 000000000..159aacea2 --- /dev/null +++ b/examples/tls/cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFPjCCAyYCCQDvLYiYD+jqeTANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMRAwDgYDVQQKDAdDb21wYW55MQww +CgYDVQQLDANPcmcxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xODAxMjUx +NzQ2MDFaFw0xOTAxMjUxNzQ2MDFaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD +QTELMAkGA1UEBwwCU0YxEDAOBgNVBAoMB0NvbXBhbnkxDDAKBgNVBAsMA09yZzEY +MBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA2WzIA2IpVR9Tb9EFhITlxuhE5rY2a3S6qzYNzQVgSFggxXEPn8k1 +sQEcer5BfAP986Sck3H0FvB4Bt/I8PwOtUCmhwcc8KtB5TcGPR4fjXnrpC+MIK5U +NLkwuyBDKziYzTdBj8kUFX1WxmvEHEgqToPOZfBgsS71cJAR/zOWraDLSRM54jXy +voLZN4Ti9rQagQrvTQ44Vz5ycDQy7UxtbUGh1CVv69vNVr7/SOOh/Nw5FNOZWLWr +odGyoec5wh9iqRZgRqiTUc6Lt7V2RWc2X2gjwST2UfI+U46Ip3oaQ7ZD4eAkoqND +xdniBZAykVG3c/99ux4BAESTF8fsNch6UticBxYMuTu+ouvP0psfI9wwwNliJDmA +CRUTB9AgRynbL1AzhqQoDfsb98IZfjfNOpwnwuLwpMAPhbgd5KNdZaIJ4Hb6/stI +yFElOExxd3TAxF2Gshd/lq1JcNHAZ1DSXV5MvOWT/NWgXwbIzUgQ8eIi+HuDYX2U +UuaB6R8tbd52H7rbUv6HrfinuSlKWqjSYLkiKHkwUpoMw8y9UycRSzs1E9nPwPTO +vRXb0mNCQeBCV9FvStNVXdCUTT8LGPv87xSD2pmt7LijlE6mHLG8McfcWkzA69un +CEHIFAFDimTuN7EBljc119xWFTcHMyoZAfFF+oTqwSbBGImruCxnaJECAwEAATAN +BgkqhkiG9w0BAQsFAAOCAgEApavsgsn7SpPHfhDSN5iZs1ILZQRewJg0Bty0xPfk +3tynSW6bNH3nSaKbpsdmxxomthNSQgD2heOq1By9YzeOoNR+7Pk3s4FkASnf3ToI +JNTUasBFFfaCG96s4Yvs8KiWS/k84yaWuU8c3Wb1jXs5Rv1qE1Uvuwat1DSGXSoD +JNluuIkCsC4kWkyq5pWCGQrabWPRTWsHwC3PTcwSRBaFgYLJaR72SloHB1ot02zL +d2age9dmFRFLLCBzP+D7RojBvL37qS/HR+rQ4SoQwiVc/JzaeqSe7ZbvEH9sZYEu +ALowJzgbwro7oZflwTWunSeSGDSltkqKjvWvZI61pwfHKDahUTmZ5h2y67FuGEaC +CIOUI8dSVSPKITxaq3JL4ze2e9/0Lt7hj19YK2uUmtMAW5Tirz4Yx5lyGH9U8Wur +y/X8VPxTc4A9TMlJgkyz0hqvhbPOT/zSWB10zXh0glKAsSBryAOEDxV1UygmSir7 +YV8Qaq+oyKUTMc1MFq5vZ07M51EPaietn85t8V2Y+k/8XYltRp32NxsypxAJuyxh +g/ko6RVTrWa1sMvz/F9LFqAdKiK5eM96lh9IU4xiLg4ob8aS/GRAA8oIFkZFhLrt +tOwjIUPmEPyHWFi8dLpNuQKYalLYhuwZftG/9xV+wqhKGZO9iPrpHSYBRTap8w2y +1QU= +-----END CERTIFICATE----- diff --git a/examples/tls/identity.pfx b/examples/tls/identity.pfx deleted file mode 100644 index ac69a0289..000000000 Binary files a/examples/tls/identity.pfx and /dev/null differ diff --git a/examples/tls/key.pem b/examples/tls/key.pem new file mode 100644 index 000000000..aac387c64 --- /dev/null +++ b/examples/tls/key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/examples/tls/src/main.rs b/examples/tls/src/main.rs index 03a3e5067..ccdf454df 100644 --- a/examples/tls/src/main.rs +++ b/examples/tls/src/main.rs @@ -2,11 +2,10 @@ extern crate actix; extern crate actix_web; extern crate env_logger; - -use std::fs::File; -use std::io::Read; +extern crate openssl; use actix_web::*; +use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype}; /// simple handle @@ -20,15 +19,15 @@ fn index(req: HttpRequest) -> Result { fn main() { if ::std::env::var("RUST_LOG").is_err() { - ::std::env::set_var("RUST_LOG", "actix_web=trace"); + ::std::env::set_var("RUST_LOG", "actix_web=info"); } let _ = env_logger::init(); let sys = actix::System::new("ws-example"); - let mut file = File::open("identity.pfx").unwrap(); - let mut pkcs12 = vec![]; - file.read_to_end(&mut pkcs12).unwrap(); - let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap().parse("12345").unwrap(); + // load ssl keys + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap(); + builder.set_certificate_chain_file("cert.pem").unwrap(); let addr = HttpServer::new( || Application::new() @@ -44,7 +43,7 @@ fn main() { .body(Body::Empty) }))) .bind("127.0.0.1:8443").unwrap() - .start_ssl(&pkcs12).unwrap(); + .start_ssl(builder).unwrap(); println!("Started http server: 127.0.0.1:8443"); let _ = sys.run(); diff --git a/guide/src/qs_13.md b/guide/src/qs_13.md index c6db174b4..d0d794979 100644 --- a/guide/src/qs_13.md +++ b/guide/src/qs_13.md @@ -12,24 +12,26 @@ With enable `alpn` feature `HttpServer` provides ```toml [dependencies] -actix-web = { git = "https://github.com/actix/actix-web", features=["alpn"] } +actix-web = { version = "0.3.3", features=["alpn"] } +openssl = { version="0.10", features = ["v110"] } ``` ```rust,ignore use std::fs::File; use actix_web::*; +use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype}; fn main() { - let mut file = File::open("identity.pfx").unwrap(); - let mut pkcs12 = vec![]; - file.read_to_end(&mut pkcs12).unwrap(); - let pkcs12 = Pkcs12::from_der(&pkcs12).unwrap().parse("12345").unwrap(); + // load ssl keys + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap(); + builder.set_certificate_chain_file("cert.pem").unwrap(); HttpServer::new( || Application::new() .resource("/index.html", |r| r.f(index))) .bind("127.0.0.1:8080").unwrap(); - .serve_ssl(pkcs12).unwrap(); + .serve_ssl(builder).unwrap(); } ``` diff --git a/src/server/srv.rs b/src/server/srv.rs index 16c7e34cd..e000c2f06 100644 --- a/src/server/srv.rs +++ b/src/server/srv.rs @@ -21,9 +21,7 @@ use native_tls::TlsAcceptor; use tokio_tls::TlsStream; #[cfg(feature="alpn")] -use openssl::ssl::{SslMethod, SslAcceptorBuilder}; -#[cfg(feature="alpn")] -use openssl::pkcs12::ParsedPkcs12; +use openssl::ssl::{AlpnError, SslAcceptorBuilder}; #[cfg(feature="alpn")] use tokio_openssl::SslStream; @@ -401,23 +399,25 @@ impl HttpServer, net::SocketAddr, H, /// Start listening for incoming tls connections. /// /// This method sets alpn protocols to "h2" and "http/1.1" - pub fn start_ssl(mut self, identity: &ParsedPkcs12) -> io::Result> { + pub fn start_ssl(mut self, mut builder: SslAcceptorBuilder) -> io::Result> + { if self.sockets.is_empty() { Err(io::Error::new(io::ErrorKind::Other, "No socket addresses are bound")) } else { + // alpn support + builder.set_alpn_protos(b"\x02h2\x08http/1.1")?; + 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) + } + }); + + let acceptor = builder.build(); let addrs: Vec<(net::SocketAddr, net::TcpListener)> = self.sockets.drain().collect(); let settings = ServerSettings::new(Some(addrs[0].0), &self.host, false); - let acceptor = match SslAcceptorBuilder::mozilla_intermediate( - SslMethod::tls(), &identity.pkey, &identity.cert, &identity.chain) - { - Ok(mut builder) => { - match builder.set_alpn_protocols(&[b"h2", b"http/1.1"]) { - Ok(_) => builder.build(), - Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)), - } - }, - Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)) - }; let workers = self.start_workers(&settings, &StreamHandlerType::Alpn(acceptor)); // start acceptors threads