Stuff roughly working
We can't shutdown in Drop since generic destructors are broken :(
This commit is contained in:
parent
a7dab3624e
commit
e2be42aa53
|
|
@ -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_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_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_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_s_mem() -> *BIO_METHOD)
|
||||||
externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO)
|
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_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)
|
externfn!(fn BIO_write(b: *BIO, buf: *c_void, len: c_int) -> c_int)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#[link(name="ssl")];
|
||||||
|
|
||||||
use std::rt::io::{Reader, Writer, Stream, Decorator};
|
use std::rt::io::{Reader, Writer, Stream, Decorator};
|
||||||
use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release};
|
use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release};
|
||||||
use std::task;
|
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 {
|
struct Ssl {
|
||||||
ssl: *ffi::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 {
|
impl Ssl {
|
||||||
fn new(ctx: &SslCtx) -> Ssl {
|
fn new(ctx: &SslCtx) -> Ssl {
|
||||||
let ssl = unsafe { ffi::SSL_new(ctx.ctx) };
|
let ssl = unsafe { ffi::SSL_new(ctx.ctx) };
|
||||||
|
|
@ -109,10 +112,11 @@ impl Ssl {
|
||||||
ffi::SSL_ERROR_WANT_READ => ErrorWantRead,
|
ffi::SSL_ERROR_WANT_READ => ErrorWantRead,
|
||||||
ffi::SSL_ERROR_WANT_WRITE => ErrorWantWrite,
|
ffi::SSL_ERROR_WANT_WRITE => ErrorWantWrite,
|
||||||
ffi::SSL_ERROR_WANT_X509_LOOKUP => ErrorWantX509Lookup,
|
ffi::SSL_ERROR_WANT_X509_LOOKUP => ErrorWantX509Lookup,
|
||||||
|
ffi::SSL_ERROR_SYSCALL => ErrorSyscall,
|
||||||
ffi::SSL_ERROR_ZERO_RETURN => ErrorZeroReturn,
|
ffi::SSL_ERROR_ZERO_RETURN => ErrorZeroReturn,
|
||||||
ffi::SSL_ERROR_WANT_CONNECT => ErrorWantConnect,
|
ffi::SSL_ERROR_WANT_CONNECT => ErrorWantConnect,
|
||||||
ffi::SSL_ERROR_WANT_ACCEPT => ErrorWantAccept,
|
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
|
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 {
|
struct MemBio {
|
||||||
bio: *ffi::BIO
|
bio: *ffi::BIO
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MemBio {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { ffi::BIO_free(self.bio); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MemBio {
|
impl MemBio {
|
||||||
fn new() -> MemBio {
|
fn new() -> MemBio {
|
||||||
let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) };
|
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));
|
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> {
|
impl<S: Stream> Reader for SslStream<S> {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
extern mod ssl;
|
extern mod ssl;
|
||||||
|
|
||||||
use std::rt::io::{Writer};
|
use std::rt::io::{Writer, Reader};
|
||||||
use std::rt::io::net::tcp::TcpStream;
|
use std::rt::io::net::tcp::TcpStream;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
|
|
@ -13,14 +13,17 @@ fn test_new_ctx() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_sslstream() {
|
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);
|
SslStream::new(SslCtx::new(Sslv23), stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_write() {
|
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);
|
let mut stream = SslStream::new(SslCtx::new(Sslv23), stream);
|
||||||
stream.write("hello".as_bytes());
|
stream.write("hello".as_bytes());
|
||||||
stream.flush();
|
stream.flush();
|
||||||
|
stream.write(" there".as_bytes());
|
||||||
|
stream.flush();
|
||||||
|
stream.shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue