@@ -8,12 +8,21 @@ use std::io::net::ip::{SocketAddr, ToSocketAddr, Port};
88use std:: io:: net:: tcp:: { TcpStream , TcpListener , TcpAcceptor } ;
99use std:: mem;
1010use std:: raw:: { self , TraitObject } ;
11+ use std:: sync:: Arc ;
1112
1213use uany:: UnsafeAnyExt ;
1314use openssl:: ssl:: { Ssl , SslStream , SslContext , VerifyCallback } ;
14- use openssl:: ssl:: SslVerifyMode :: SslVerifyPeer ;
15+ use openssl:: ssl:: SslVerifyMode :: { SslVerifyPeer , SslVerifyNone } ;
1516use openssl:: ssl:: SslMethod :: Sslv23 ;
1617use 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 {
184193pub 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
191200impl 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
214232impl 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}
0 commit comments