use read_until_slice::AsyncBufReadUntilSliceExt;
use std::str::from_utf8;
use tokio::io::{copy, sink, split, AsyncWriteExt, BufReader};
use tokio::join;
use tokio::net::{lookup_host, TcpStream};
#[tokio::main(flavor = "current_thread")]
async fn main() {
let addr = lookup_host("httpbingo.org:80")
.await
.ok()
.and_then(|mut it| it.next())
.unwrap();
let stream = TcpStream::connect(addr).await.unwrap();
let (reader, mut writer) = split(stream);
let mut reader = BufReader::new(reader);
let request = b"\
GET /status/200 HTTP/1.1\r\n\
Host: httpbingo.org\r\n\
Connection: close\r\n\
User-Agent: crate/example/read_until_slice\r\n\
\r\n";
println!("{}", from_utf8(request).unwrap());
join!(
async move {
writer.write_all(request).await.unwrap();
},
async {
let mut buffer = vec![];
let _ = reader.read_until_slice(b"\r\n", &mut buffer).await.unwrap();
assert!(buffer.ends_with(b"\r\n"));
let status_line = &buffer[..buffer.len() - 2];
println!("{}", status_line.escape_ascii());
let mut split = status_line.split(|&b| b == b' ');
let http_version = split.next().unwrap();
assert_eq!(http_version, b"HTTP/1.1");
let status_code = split.next().unwrap();
assert_eq!(status_code, b"200");
let status_text = split.next().unwrap();
assert_eq!(status_text, b"OK");
loop {
buffer.clear();
let _ = reader.read_until_slice(b"\r\n", &mut buffer).await.unwrap();
assert!(buffer.ends_with(b"\r\n"));
let header_line = &buffer[..buffer.len() - 2];
println!("{}", header_line.escape_ascii());
if header_line.is_empty() {
break;
};
}
copy(&mut reader, &mut sink()).await.unwrap();
}
);
}