Stuff roughly working

We can't shutdown in Drop since generic destructors are broken :(
This commit is contained in:
Steven Fackler 2013-10-05 20:36:45 -07:00
parent a7dab3624e
commit e2be42aa53
3 changed files with 41 additions and 23 deletions

View File

@ -37,9 +37,9 @@ externfn!(fn SSL_connect(ssl: *SSL) -> c_int)
externfn!(fn SSL_get_error(ssl: *SSL, ret: c_int) -> c_int)
externfn!(fn SSL_read(ssl: *SSL, buf: *c_void, num: c_int) -> c_int)
externfn!(fn SSL_write(ssl: *SSL, buf: *c_void, num: c_int) -> c_int)
externfn!(fn SSL_shutdown(ssl: *SSL) -> c_int)
externfn!(fn BIO_s_mem() -> *BIO_METHOD)
externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO)
externfn!(fn BIO_free(a: *BIO) -> c_int)
externfn!(fn BIO_read(b: *BIO, buf: *c_void, len: c_int) -> c_int)
externfn!(fn BIO_write(b: *BIO, buf: *c_void, len: c_int) -> c_int)

View File

@ -1,3 +1,5 @@
#[link(name="ssl")];
use std::rt::io::{Reader, Writer, Stream, Decorator};
use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release};
use std::task;
@ -60,6 +62,19 @@ impl SslCtx {
}
}
#[deriving(Eq, TotalEq, ToStr)]
enum SslError {
ErrorNone,
ErrorSsl,
ErrorWantRead,
ErrorWantWrite,
ErrorWantX509Lookup,
ErrorSyscall,
ErrorZeroReturn,
ErrorWantConnect,
ErrorWantAccept,
}
struct Ssl {
ssl: *ffi::SSL
}
@ -70,18 +85,6 @@ impl Drop for Ssl {
}
}
#[deriving(Eq, TotalEq, ToStr)]
enum SslError {
ErrorNone,
ErrorSsl,
ErrorWantRead,
ErrorWantWrite,
ErrorWantX509Lookup,
ErrorZeroReturn,
ErrorWantConnect,
ErrorWantAccept,
}
impl Ssl {
fn new(ctx: &SslCtx) -> Ssl {
let ssl = unsafe { ffi::SSL_new(ctx.ctx) };
@ -109,10 +112,11 @@ impl Ssl {
ffi::SSL_ERROR_WANT_READ => ErrorWantRead,
ffi::SSL_ERROR_WANT_WRITE => ErrorWantWrite,
ffi::SSL_ERROR_WANT_X509_LOOKUP => ErrorWantX509Lookup,
ffi::SSL_ERROR_SYSCALL => ErrorSyscall,
ffi::SSL_ERROR_ZERO_RETURN => ErrorZeroReturn,
ffi::SSL_ERROR_WANT_CONNECT => ErrorWantConnect,
ffi::SSL_ERROR_WANT_ACCEPT => ErrorWantAccept,
_ => unreachable!()
err => fail2!("Unknown error {}", err)
}
}
@ -129,18 +133,17 @@ impl Ssl {
buf.len() as c_int) as int
}
}
fn shutdown(&self) -> int {
unsafe { ffi::SSL_shutdown(self.ssl) as int }
}
}
// BIOs are freed by SSL_free
struct MemBio {
bio: *ffi::BIO
}
impl Drop for MemBio {
fn drop(&mut self) {
unsafe { ffi::BIO_free(self.bio); }
}
}
impl MemBio {
fn new() -> MemBio {
let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) };
@ -240,6 +243,18 @@ impl<S: Stream> SslStream<S> {
self.stream.write(self.buf.slice_to(len));
}
}
pub fn shutdown(&mut self) {
loop {
let ret = do self.in_retry_wrapper |ssl| {
ssl.ssl.shutdown()
};
if ret != Ok(0) {
break;
}
}
}
}
impl<S: Stream> Reader for SslStream<S> {

View File

@ -1,6 +1,6 @@
extern mod ssl;
use std::rt::io::{Writer};
use std::rt::io::{Writer, Reader};
use std::rt::io::net::tcp::TcpStream;
use std::vec;
@ -13,14 +13,17 @@ fn test_new_ctx() {
#[test]
fn test_new_sslstream() {
let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap());
let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
SslStream::new(SslCtx::new(Sslv23), stream);
}
#[test]
fn test_write() {
let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap());
let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
let mut stream = SslStream::new(SslCtx::new(Sslv23), stream);
stream.write("hello".as_bytes());
stream.flush();
stream.write(" there".as_bytes());
stream.flush();
stream.shutdown();
}