Skip to content

Commit d80d3e0

Browse files
committed
Merge pull request #240 from cactorium/ssltry3
Added TLS/SSL support serverside
2 parents 6442635 + c6eef68 commit d80d3e0

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/net.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ use std::io::net::ip::{SocketAddr, ToSocketAddr, Port};
88
use std::io::net::tcp::{TcpStream, TcpListener, TcpAcceptor};
99
use std::mem;
1010
use std::raw::{self, TraitObject};
11+
use std::sync::Arc;
1112

1213
use uany::UnsafeAnyExt;
1314
use openssl::ssl::{Ssl, SslStream, SslContext, VerifyCallback};
14-
use openssl::ssl::SslVerifyMode::SslVerifyPeer;
15+
use openssl::ssl::SslVerifyMode::{SslVerifyPeer, SslVerifyNone};
1516
use openssl::ssl::SslMethod::Sslv23;
1617
use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed};
18+
use openssl::x509::X509FileType;
19+
20+
macro_rules! try_some {
21+
($expr:expr) => (match $expr {
22+
Some(val) => { return Err(val); },
23+
_ => {}
24+
})
25+
}
1726

1827
/// The write-status indicating headers have not been written.
1928
#[allow(missing_copy_implementations)]
@@ -184,8 +193,8 @@ impl NetworkStream {
184193
pub enum HttpListener {
185194
/// Http variant.
186195
Http,
187-
/// Https variant.
188-
Https,
196+
/// Https variant. The two paths point to the certificate and key PEM files, in that order.
197+
Https(Path, Path),
189198
}
190199

191200
impl NetworkListener for HttpListener {
@@ -197,7 +206,16 @@ impl NetworkListener for HttpListener {
197206
let addr = try!(tcp.socket_name());
198207
Ok(match *self {
199208
HttpListener::Http => HttpAcceptor::Http(try!(tcp.listen()), addr),
200-
HttpListener::Https => unimplemented!(),
209+
HttpListener::Https(ref cert, ref key) => {
210+
let mut ssl_context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error));
211+
try_some!(ssl_context.set_cipher_list("DEFAULT").map(lift_ssl_error));
212+
try_some!(ssl_context.set_certificate_file(
213+
cert, X509FileType::PEM).map(lift_ssl_error));
214+
try_some!(ssl_context.set_private_key_file(
215+
key, X509FileType::PEM).map(lift_ssl_error));
216+
ssl_context.set_verify(SslVerifyNone, None);
217+
HttpAcceptor::Https(try!(tcp.listen()), addr, Arc::new(ssl_context))
218+
}
201219
})
202220
}
203221
}
@@ -208,7 +226,7 @@ pub enum HttpAcceptor {
208226
/// Http variant.
209227
Http(TcpAcceptor, SocketAddr),
210228
/// Https variant.
211-
Https(TcpAcceptor, SocketAddr),
229+
Https(TcpAcceptor, SocketAddr, Arc<SslContext>),
212230
}
213231

214232
impl NetworkAcceptor for HttpAcceptor {
@@ -218,23 +236,28 @@ impl NetworkAcceptor for HttpAcceptor {
218236
fn accept(&mut self) -> IoResult<HttpStream> {
219237
Ok(match *self {
220238
HttpAcceptor::Http(ref mut tcp, _) => HttpStream::Http(try!(tcp.accept())),
221-
HttpAcceptor::Https(ref mut _tcp, _) => unimplemented!(),
239+
HttpAcceptor::Https(ref mut tcp, _, ref ssl_context) => {
240+
let stream = try!(tcp.accept());
241+
let ssl_stream = try!(SslStream::<TcpStream>::new_server(&**ssl_context, stream).
242+
map_err(lift_ssl_error));
243+
HttpStream::Https(ssl_stream)
244+
}
222245
})
223246
}
224247

225248
#[inline]
226249
fn close(&mut self) -> IoResult<()> {
227250
match *self {
228251
HttpAcceptor::Http(ref mut tcp, _) => tcp.close_accept(),
229-
HttpAcceptor::Https(ref mut tcp, _) => tcp.close_accept(),
252+
HttpAcceptor::Https(ref mut tcp, _, _) => tcp.close_accept(),
230253
}
231254
}
232255

233256
#[inline]
234257
fn socket_name(&self) -> IoResult<SocketAddr> {
235258
match *self {
236259
HttpAcceptor::Http(_, addr) => Ok(addr),
237-
HttpAcceptor::Https(_, addr) => Ok(addr),
260+
HttpAcceptor::Https(_, addr, _) => Ok(addr),
238261
}
239262
}
240263
}

src/server/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ impl Server<HttpListener> {
4646
pub fn http(ip: IpAddr, port: Port) -> Server {
4747
Server::with_listener(ip, port, HttpListener::Http)
4848
}
49+
/// Creates a new server that will handler `HttpStreams`s using a TLS connection.
50+
pub fn https(ip: IpAddr, port: Port, cert: Path, key: Path) -> Server {
51+
Server::with_listener(ip, port, HttpListener::Https(cert, key))
52+
}
4953
}
5054

5155
impl<

0 commit comments

Comments
 (0)