[Improved] MidHandshake/TlsStream

- [Improved] README.md
- [Improved] MidHandshake poll
- [Improved] TlsStream read
- [Fixed] TlsStream write, possible of repeat write
- [Removed] TlsStream poll_{read, write}
This commit is contained in:
quininer kel 2017-02-27 20:59:35 +08:00
parent 9394405512
commit 7e4fcca032
2 changed files with 43 additions and 31 deletions

View File

@ -4,3 +4,21 @@
[![docs.rs](https://docs.rs/tokio-rustls/badge.svg)](https://docs.rs/tokio-rustls/) [![docs.rs](https://docs.rs/tokio-rustls/badge.svg)](https://docs.rs/tokio-rustls/)
[tokio-tls](https://github.com/tokio-rs/tokio-tls) fork, use [rustls](https://github.com/ctz/rustls). [tokio-tls](https://github.com/tokio-rs/tokio-tls) fork, use [rustls](https://github.com/ctz/rustls).
### exmaple
```rust
// ...
use rustls::ClientConfig;
use tokio_rustls::ClientConfigExt;
let mut config = ClientConfig::new();
config.root_store.add_trust_anchors(&webpki_roots::ROOTS);
let config = Arc::new(config);
TcpStream::connect(&addr, &handle)
.and_then(|socket| config.connect_async("www.rust-lang.org", socket))
// ...
```

View File

@ -98,12 +98,10 @@ impl<S, C> Future for MidHandshake<S, C>
if !stream.session.is_handshaking() { break }; if !stream.session.is_handshaking() { break };
match stream.do_io() { match stream.do_io() {
Ok(()) => if stream.eof { Ok(()) => match (stream.eof, stream.session.is_handshaking()) {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof)) (true, true) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
} else if stream.session.is_handshaking() { (false, true) => continue,
continue (..) => break
} else {
break
}, },
Err(e) => match (e.kind(), stream.session.is_handshaking()) { Err(e) => match (e.kind(), stream.session.is_handshaking()) {
(io::ErrorKind::WouldBlock, true) => return Ok(Async::NotReady), (io::ErrorKind::WouldBlock, true) => return Ok(Async::NotReady),
@ -189,11 +187,17 @@ impl<S, C> io::Read for TlsStream<S, C>
where S: Io, C: Session where S: Io, C: Session
{ {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
loop {
match self.session.read(buf) {
Ok(0) if !self.eof => self.do_io()?,
Ok(n) => return Ok(n),
Err(e) => if e.kind() == io::ErrorKind::ConnectionAborted {
self.do_io()?; self.do_io()?;
if self.eof { return if self.eof { Ok(0) } else { Err(e) }
Ok(0)
} else { } else {
self.session.read(buf) return Err(e)
}
}
} }
} }
} }
@ -202,11 +206,17 @@ impl<S, C> io::Write for TlsStream<S, C>
where S: Io, C: Session where S: Io, C: Session
{ {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let output = self.session.write(buf); let output = self.session.write(buf)?;
while self.session.wants_write() && self.io.poll_write().is_ready() { while self.session.wants_write() && self.io.poll_write().is_ready() {
self.session.write_tls(&mut self.io)?; match self.session.write_tls(&mut self.io) {
Ok(_) => (),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => break,
Err(e) => return Err(e)
} }
output }
Ok(output)
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
@ -218,20 +228,4 @@ impl<S, C> io::Write for TlsStream<S, C>
} }
} }
impl<S, C> Io for TlsStream<S, C> where S: Io, C: Session { impl<S, C> Io for TlsStream<S, C> where S: Io, C: Session {}
fn poll_read(&mut self) -> Async<()> {
if !self.eof && self.session.wants_read() && self.io.poll_read().is_not_ready() {
Async::NotReady
} else {
Async::Ready(())
}
}
fn poll_write(&mut self) -> Async<()> {
if self.session.wants_write() && self.io.poll_write().is_not_ready() {
Async::NotReady
} else {
Async::Ready(())
}
}
}