publish 0.12.0-alpha.1

This commit is contained in:
quininer 2019-08-11 00:00:49 +08:00
parent bbc6688292
commit 0fceadf799
4 changed files with 102 additions and 117 deletions

View File

@ -15,8 +15,8 @@ matrix:
- rust: stable - rust: stable
script: script:
- cargo test --test test - cargo test
# - cargo test --features early-data - cargo test --features early-data
# - cd examples/server # - cd examples/server
# - cargo check # - cargo check
# - cd ../../examples/client # - cd ../../examples/client

View File

@ -1,6 +1,6 @@
[package] [package]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.12.0-alpha" version = "0.12.0-alpha.1"
authors = ["quininer kel <quininer@live.com>"] authors = ["quininer kel <quininer@live.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
repository = "https://github.com/quininer/tokio-rustls" repository = "https://github.com/quininer/tokio-rustls"

View File

@ -1,7 +1,9 @@
use std::pin::Pin; use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::task::{ Poll, Context }; use std::task::{ Poll, Context };
use futures_core::ready;
use futures_util::future::poll_fn; use futures_util::future::poll_fn;
use futures_util::task::noop_waker_ref;
use tokio_io::{ AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt }; use tokio_io::{ AsyncRead, AsyncWrite, AsyncReadExt, AsyncWriteExt };
use std::io::{ self, Read, Write, BufReader, Cursor }; use std::io::{ self, Read, Write, BufReader, Cursor };
use webpki::DNSNameRef; use webpki::DNSNameRef;
@ -14,7 +16,7 @@ use rustls::{
use super::Stream; use super::Stream;
struct Good<'a>(&'a mut Session); struct Good<'a>(&'a mut dyn Session);
impl<'a> AsyncRead for Good<'a> { impl<'a> AsyncRead for Good<'a> {
fn poll_read(mut self: Pin<&mut Self>, _cx: &mut Context<'_>, mut buf: &mut [u8]) -> Poll<io::Result<usize>> { fn poll_read(mut self: Pin<&mut Self>, _cx: &mut Context<'_>, mut buf: &mut [u8]) -> Poll<io::Result<usize>> {
@ -34,7 +36,7 @@ impl<'a> AsyncWrite for Good<'a> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
} }
@ -60,122 +62,104 @@ impl AsyncWrite for Bad {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
} }
#[test] #[tokio::test]
fn stream_good() -> io::Result<()> { async fn stream_good() -> io::Result<()> {
const FILE: &'static [u8] = include_bytes!("../../README.md"); const FILE: &'static [u8] = include_bytes!("../../README.md");
let fut = async { let (mut server, mut client) = make_pair();
let (mut server, mut client) = make_pair(); poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?; io::copy(&mut Cursor::new(FILE), &mut server)?;
io::copy(&mut Cursor::new(FILE), &mut server)?;
{
let mut good = Good(&mut server);
let mut stream = Stream::new(&mut good, &mut client);
let mut buf = Vec::new();
stream.read_to_end(&mut buf).await?;
assert_eq!(buf, FILE);
stream.write_all(b"Hello World!").await?;
}
let mut buf = String::new();
server.read_to_string(&mut buf)?;
assert_eq!(buf, "Hello World!");
Ok(()) as io::Result<()>
};
executor::block_on(fut)
}
#[test]
fn stream_bad() -> io::Result<()> {
let fut = async {
let (mut server, mut client) = make_pair();
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
client.set_buffer_limit(1024);
let mut bad = Bad(true);
let mut stream = Stream::new(&mut bad, &mut client);
assert_eq!(poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x42; 8])).await?, 8);
assert_eq!(poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x42; 8])).await?, 8);
let r = poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x00; 1024])).await?; // fill buffer
assert!(r < 1024);
let ret = poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x01]));
assert!(ret.is_pending());
Ok(()) as io::Result<()>
};
executor::block_on(fut)
}
#[test]
fn stream_handshake() -> io::Result<()> {
let fut = async {
let (mut server, mut client) = make_pair();
{
let mut good = Good(&mut server);
let mut stream = Stream::new(&mut good, &mut client);
let (r, w) = poll_fn(|cx| stream.complete_io(cx)).await?;
assert!(r > 0);
assert!(w > 0);
poll_fn(|cx| stream.complete_io(cx)).await?; // finish server handshake
}
assert!(!server.is_handshaking());
assert!(!client.is_handshaking());
Ok(()) as io::Result<()>
};
executor::block_on(fut)
}
#[test]
fn stream_handshake_eof() -> io::Result<()> {
let fut = async {
let (_, mut client) = make_pair();
let mut bad = Bad(false);
let mut stream = Stream::new(&mut bad, &mut client);
let r = poll_fn(|cx| stream.complete_io(&mut cx)).await?;
assert_eq!(r.map_err(|err| err.kind()), Poll::Ready(Err(io::ErrorKind::UnexpectedEof)));
Ok(()) as io::Result<()>
};
executor::block_on(fut)
}
#[test]
fn stream_eof() -> io::Result<()> {
let fut = async {
let (mut server, mut client) = make_pair();
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
{
let mut good = Good(&mut server); let mut good = Good(&mut server);
let mut stream = Stream::new(&mut good, &mut client).set_eof(true); let mut stream = Stream::new(&mut good, &mut client);
let mut buf = Vec::new(); let mut buf = Vec::new();
stream.read_to_end(&mut buf).await?; stream.read_to_end(&mut buf).await?;
assert_eq!(buf.len(), 0); assert_eq!(buf, FILE);
stream.write_all(b"Hello World!").await?;
}
Ok(()) as io::Result<()> let mut buf = String::new();
}; server.read_to_string(&mut buf)?;
assert_eq!(buf, "Hello World!");
executor::block_on(fut) Ok(()) as io::Result<()>
}
#[tokio::test]
async fn stream_bad() -> io::Result<()> {
let (mut server, mut client) = make_pair();
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
client.set_buffer_limit(1024);
let mut bad = Bad(true);
let mut stream = Stream::new(&mut bad, &mut client);
assert_eq!(poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x42; 8])).await?, 8);
assert_eq!(poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x42; 8])).await?, 8);
let r = poll_fn(|cx| stream.as_mut_pin().poll_write(cx, &[0x00; 1024])).await?; // fill buffer
assert!(r < 1024);
let mut cx = Context::from_waker(noop_waker_ref());
let ret = stream.as_mut_pin().poll_write(&mut cx, &[0x01]);
assert!(ret.is_pending());
Ok(()) as io::Result<()>
}
#[tokio::test]
async fn stream_handshake() -> io::Result<()> {
let (mut server, mut client) = make_pair();
{
let mut good = Good(&mut server);
let mut stream = Stream::new(&mut good, &mut client);
let (r, w) = poll_fn(|cx| stream.complete_io(cx)).await?;
assert!(r > 0);
assert!(w > 0);
poll_fn(|cx| stream.complete_io(cx)).await?; // finish server handshake
}
assert!(!server.is_handshaking());
assert!(!client.is_handshaking());
Ok(()) as io::Result<()>
}
#[tokio::test]
async fn stream_handshake_eof() -> io::Result<()> {
let (_, mut client) = make_pair();
let mut bad = Bad(false);
let mut stream = Stream::new(&mut bad, &mut client);
let mut cx = Context::from_waker(noop_waker_ref());
let r = stream.complete_io(&mut cx);
assert_eq!(r.map_err(|err| err.kind()), Poll::Ready(Err(io::ErrorKind::UnexpectedEof)));
Ok(()) as io::Result<()>
}
#[tokio::test]
async fn stream_eof() -> io::Result<()> {
let (mut server, mut client) = make_pair();
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
let mut good = Good(&mut server);
let mut stream = Stream::new(&mut good, &mut client).set_eof(true);
let mut buf = Vec::new();
stream.read_to_end(&mut buf).await?;
assert_eq!(buf.len(), 0);
Ok(()) as io::Result<()>
} }
fn make_pair() -> (ServerSession, ClientSession) { fn make_pair() -> (ServerSession, ClientSession) {
@ -203,11 +187,11 @@ fn do_handshake(client: &mut ClientSession, server: &mut ServerSession, cx: &mut
let mut stream = Stream::new(&mut good, client); let mut stream = Stream::new(&mut good, client);
if stream.session.is_handshaking() { if stream.session.is_handshaking() {
futures::ready!(stream.complete_io(cx))?; ready!(stream.complete_io(cx))?;
} }
if stream.session.wants_write() { if stream.session.wants_write() {
futures::ready!(stream.complete_io(cx))?; ready!(stream.complete_io(cx))?;
} }
Poll::Ready(Ok(())) Poll::Ready(Ok(()))

View File

@ -1,9 +1,8 @@
use std::io; use std::io;
use std::sync::Arc; use std::sync::Arc;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use futures::executor; use tokio::prelude::*;
use futures::prelude::*; use tokio::net::TcpStream;
use romio::tcp::TcpStream;
use rustls::ClientConfig; use rustls::ClientConfig;
use crate::{ TlsConnector, client::TlsStream }; use crate::{ TlsConnector, client::TlsStream };
@ -28,19 +27,21 @@ async fn get(config: Arc<ClientConfig>, domain: &str, rtt0: bool)
Ok((stream, String::from_utf8(buf).unwrap())) Ok((stream, String::from_utf8(buf).unwrap()))
} }
#[test] #[tokio::test]
fn test_0rtt() { async fn test_0rtt() -> io::Result<()> {
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
config.enable_early_data = true; config.enable_early_data = true;
let config = Arc::new(config); let config = Arc::new(config);
let domain = "mozilla-modern.badssl.com"; let domain = "mozilla-modern.badssl.com";
let (_, output) = executor::block_on(get(config.clone(), domain, false)).unwrap(); let (_, output) = get(config.clone(), domain, false).await?;
assert!(output.contains("<title>mozilla-modern.badssl.com</title>")); assert!(output.contains("<title>mozilla-modern.badssl.com</title>"));
let (io, output) = executor::block_on(get(config.clone(), domain, true)).unwrap(); let (io, output) = get(config.clone(), domain, true).await?;
assert!(output.contains("<title>mozilla-modern.badssl.com</title>")); assert!(output.contains("<title>mozilla-modern.badssl.com</title>"));
assert_eq!(io.early_data.0, 0); assert_eq!(io.early_data.0, 0);
Ok(())
} }