1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-25 00:12:59 +01:00
actix-extras/src/payload.rs

711 lines
20 KiB
Rust
Raw Normal View History

2017-12-19 09:18:57 +01:00
//! Payload stream
2017-11-07 01:23:58 +01:00
use bytes::{Bytes, BytesMut};
2018-04-14 01:02:01 +02:00
use futures::task::{current as current_task, Task};
2018-02-27 01:11:00 +01:00
use futures::{Async, Poll, Stream};
2018-04-14 01:02:01 +02:00
use std::cell::RefCell;
use std::cmp;
use std::collections::VecDeque;
use std::rc::{Rc, Weak};
2017-10-09 05:16:48 +02:00
2017-11-16 07:06:28 +01:00
use error::PayloadError;
2017-10-27 08:14:33 +02:00
/// max buffer size 32k
pub(crate) const MAX_BUFFER_SIZE: usize = 32_768;
#[derive(Debug, PartialEq)]
pub(crate) enum PayloadStatus {
Read,
Pause,
Dropped,
}
2017-12-19 09:29:25 +01:00
/// Buffered stream of bytes chunks
2017-10-09 05:16:48 +02:00
///
2018-04-14 01:02:01 +02:00
/// Payload stores chunks in a vector. First chunk can be received with
/// `.readany()` method. Payload stream is not thread safe. Payload does not
/// notify current task when new data is available.
2017-12-19 09:29:25 +01:00
///
/// Payload stream can be used as `HttpResponse` body stream.
2017-10-19 08:43:50 +02:00
#[derive(Debug)]
2017-10-09 05:16:48 +02:00
pub struct Payload {
inner: Rc<RefCell<Inner>>,
}
impl Payload {
2017-12-19 06:58:38 +01:00
/// Create payload stream.
///
2018-04-14 01:02:01 +02:00
/// This method construct two objects responsible for bytes stream
/// generation.
2017-12-19 06:58:38 +01:00
///
/// * `PayloadSender` - *Sender* side of the stream
///
/// * `Payload` - *Receiver* side of the stream
pub fn new(eof: bool) -> (PayloadSender, Payload) {
2017-10-09 05:16:48 +02:00
let shared = Rc::new(RefCell::new(Inner::new(eof)));
2018-04-14 01:02:01 +02:00
(
PayloadSender {
inner: Rc::downgrade(&shared),
},
2018-04-29 18:09:08 +02:00
Payload { inner: shared },
2018-04-14 01:02:01 +02:00
)
2017-10-09 05:16:48 +02:00
}
2017-11-27 04:00:57 +01:00
/// Create empty payload
#[doc(hidden)]
pub fn empty() -> Payload {
2018-04-14 01:02:01 +02:00
Payload {
inner: Rc::new(RefCell::new(Inner::new(true))),
}
2017-11-27 04:00:57 +01:00
}
2017-10-09 05:16:48 +02:00
/// Length of the data in this payload
2018-06-25 06:58:04 +02:00
#[cfg(test)]
2017-10-09 05:16:48 +02:00
pub fn len(&self) -> usize {
self.inner.borrow().len()
}
/// Is payload empty
2018-06-25 06:58:04 +02:00
#[cfg(test)]
2017-10-09 05:16:48 +02:00
pub fn is_empty(&self) -> bool {
self.inner.borrow().len() == 0
}
/// Put unused data back to payload
2018-01-11 06:02:28 +01:00
#[inline]
2017-10-14 01:33:23 +02:00
pub fn unread_data(&mut self, data: Bytes) {
2017-10-09 05:16:48 +02:00
self.inner.borrow_mut().unread_data(data);
}
2017-11-04 17:07:44 +01:00
2018-02-27 01:11:00 +01:00
#[cfg(test)]
pub(crate) fn readall(&self) -> Option<Bytes> {
self.inner.borrow_mut().readall()
}
#[inline]
/// Set read buffer capacity
///
/// Default buffer capacity is 32Kb.
pub fn set_read_buffer_capacity(&mut self, cap: usize) {
self.inner.borrow_mut().capacity = cap;
}
2017-10-09 05:16:48 +02:00
}
impl Stream for Payload {
2018-02-25 09:21:45 +01:00
type Item = Bytes;
2017-10-27 08:14:33 +02:00
type Error = PayloadError;
2017-10-09 05:16:48 +02:00
2018-01-11 06:02:28 +01:00
#[inline]
2018-02-25 09:21:45 +01:00
fn poll(&mut self) -> Poll<Option<Bytes>, PayloadError> {
2018-02-27 05:07:22 +01:00
self.inner.borrow_mut().readany()
2017-12-19 09:18:57 +01:00
}
}
impl Clone for Payload {
fn clone(&self) -> Payload {
2018-04-14 01:02:01 +02:00
Payload {
inner: Rc::clone(&self.inner),
}
2017-12-19 09:18:57 +01:00
}
}
/// Payload writer interface.
2018-02-27 05:07:22 +01:00
pub(crate) trait PayloadWriter {
2017-12-19 06:58:38 +01:00
/// Set stream error.
2017-11-06 10:24:49 +01:00
fn set_error(&mut self, err: PayloadError);
2017-12-19 06:58:38 +01:00
/// Write eof into a stream which closes reading side of a stream.
2017-11-06 10:24:49 +01:00
fn feed_eof(&mut self);
2017-12-19 06:58:38 +01:00
/// Feed bytes into a payload stream
2017-11-06 10:24:49 +01:00
fn feed_data(&mut self, data: Bytes);
2018-02-27 05:07:22 +01:00
/// Need read data
fn need_read(&self) -> PayloadStatus;
2017-11-06 10:24:49 +01:00
}
2017-12-19 06:58:38 +01:00
/// Sender part of the payload stream
pub struct PayloadSender {
2017-10-09 05:16:48 +02:00
inner: Weak<RefCell<Inner>>,
}
2017-11-06 10:24:49 +01:00
impl PayloadWriter for PayloadSender {
2018-03-09 02:19:50 +01:00
#[inline]
2017-11-06 10:24:49 +01:00
fn set_error(&mut self, err: PayloadError) {
2017-10-14 01:33:23 +02:00
if let Some(shared) = self.inner.upgrade() {
shared.borrow_mut().set_error(err)
}
}
2018-03-09 02:19:50 +01:00
#[inline]
2017-11-06 10:24:49 +01:00
fn feed_eof(&mut self) {
2017-10-09 05:16:48 +02:00
if let Some(shared) = self.inner.upgrade() {
shared.borrow_mut().feed_eof()
}
}
2018-03-09 02:19:50 +01:00
#[inline]
2017-11-06 10:24:49 +01:00
fn feed_data(&mut self, data: Bytes) {
2017-10-09 05:16:48 +02:00
if let Some(shared) = self.inner.upgrade() {
shared.borrow_mut().feed_data(data)
}
}
2018-02-10 01:20:10 +01:00
#[inline]
fn need_read(&self) -> PayloadStatus {
// we check need_read only if Payload (other side) is alive,
// otherwise always return true (consume payload)
2017-11-06 10:24:49 +01:00
if let Some(shared) = self.inner.upgrade() {
if shared.borrow().need_read {
PayloadStatus::Read
} else {
#[cfg(not(test))]
{
if shared.borrow_mut().io_task.is_none() {
shared.borrow_mut().io_task = Some(current_task());
}
}
PayloadStatus::Pause
}
2017-11-06 10:24:49 +01:00
} else {
PayloadStatus::Dropped
2017-11-06 10:24:49 +01:00
}
}
}
2017-10-19 08:43:50 +02:00
#[derive(Debug)]
2017-10-09 05:16:48 +02:00
struct Inner {
len: usize,
eof: bool,
2017-10-14 01:33:23 +02:00
err: Option<PayloadError>,
2018-02-27 05:07:22 +01:00
need_read: bool,
2017-10-09 05:16:48 +02:00
items: VecDeque<Bytes>,
capacity: usize,
task: Option<Task>,
io_task: Option<Task>,
2017-10-09 05:16:48 +02:00
}
impl Inner {
fn new(eof: bool) -> Self {
Inner {
2018-02-26 23:33:56 +01:00
eof,
2017-10-09 05:16:48 +02:00
len: 0,
2017-10-14 01:33:23 +02:00
err: None,
2017-10-09 05:16:48 +02:00
items: VecDeque::new(),
2018-03-03 05:47:23 +01:00
need_read: true,
capacity: MAX_BUFFER_SIZE,
task: None,
io_task: None,
2017-10-09 05:16:48 +02:00
}
}
2018-03-09 02:19:50 +01:00
#[inline]
2017-10-14 01:33:23 +02:00
fn set_error(&mut self, err: PayloadError) {
self.err = Some(err);
}
2018-03-09 02:19:50 +01:00
#[inline]
2017-10-09 05:16:48 +02:00
fn feed_eof(&mut self) {
self.eof = true;
}
2018-03-09 02:19:50 +01:00
#[inline]
2017-10-09 05:16:48 +02:00
fn feed_data(&mut self, data: Bytes) {
self.len += data.len();
self.items.push_back(data);
self.need_read = self.len < self.capacity;
if let Some(task) = self.task.take() {
task.notify()
}
2017-10-09 05:16:48 +02:00
}
2018-06-25 06:58:04 +02:00
#[cfg(test)]
2017-10-09 05:16:48 +02:00
fn len(&self) -> usize {
self.len
}
2018-02-27 01:11:00 +01:00
#[cfg(test)]
pub(crate) fn readall(&mut self) -> Option<Bytes> {
let len = self.items.iter().map(|b| b.len()).sum();
if len > 0 {
let mut buf = BytesMut::with_capacity(len);
for item in &self.items {
buf.extend_from_slice(item);
}
self.items = VecDeque::new();
self.len = 0;
Some(buf.take().freeze())
} else {
2018-02-27 05:07:22 +01:00
self.need_read = true;
2018-02-27 01:11:00 +01:00
None
}
}
2018-02-27 05:07:22 +01:00
fn readany(&mut self) -> Poll<Option<Bytes>, PayloadError> {
2017-10-09 05:16:48 +02:00
if let Some(data) = self.items.pop_front() {
self.len -= data.len();
self.need_read = self.len < self.capacity;
#[cfg(not(test))]
{
if self.need_read && self.task.is_none() {
self.task = Some(current_task());
}
if let Some(task) = self.io_task.take() {
task.notify()
}
}
2018-02-25 09:21:45 +01:00
Ok(Async::Ready(Some(data)))
2017-10-14 01:33:23 +02:00
} else if let Some(err) = self.err.take() {
2017-10-27 08:14:33 +02:00
Err(err)
2018-02-10 01:20:10 +01:00
} else if self.eof {
Ok(Async::Ready(None))
2017-10-09 05:16:48 +02:00
} else {
2018-02-27 05:07:22 +01:00
self.need_read = true;
#[cfg(not(test))]
{
if self.task.is_none() {
self.task = Some(current_task());
}
if let Some(task) = self.io_task.take() {
task.notify()
}
}
2017-10-27 08:14:33 +02:00
Ok(Async::NotReady)
2017-10-09 05:16:48 +02:00
}
}
2017-11-04 17:07:44 +01:00
fn unread_data(&mut self, data: Bytes) {
2017-10-09 05:16:48 +02:00
self.len += data.len();
2017-12-21 05:30:54 +01:00
self.items.push_front(data);
2017-10-09 05:16:48 +02:00
}
}
2017-10-23 04:58:50 +02:00
2018-02-26 03:55:07 +01:00
pub struct PayloadHelper<S> {
len: usize,
items: VecDeque<Bytes>,
stream: S,
}
2018-04-14 01:02:01 +02:00
impl<S> PayloadHelper<S>
where
S: Stream<Item = Bytes, Error = PayloadError>,
{
2018-02-26 03:55:07 +01:00
pub fn new(stream: S) -> Self {
PayloadHelper {
len: 0,
items: VecDeque::new(),
2018-02-26 22:58:23 +01:00
stream,
2018-02-26 03:55:07 +01:00
}
}
2018-03-27 00:58:30 +02:00
/// Get mutable reference to an inner stream.
pub fn get_mut(&mut self) -> &mut S {
&mut self.stream
}
2018-03-09 02:19:50 +01:00
#[inline]
2018-02-26 03:55:07 +01:00
fn poll_stream(&mut self) -> Poll<bool, PayloadError> {
2018-04-14 01:02:01 +02:00
self.stream.poll().map(|res| match res {
Async::Ready(Some(data)) => {
self.len += data.len();
self.items.push_back(data);
Async::Ready(true)
2018-02-26 03:55:07 +01:00
}
2018-04-14 01:02:01 +02:00
Async::Ready(None) => Async::Ready(false),
Async::NotReady => Async::NotReady,
2018-02-26 03:55:07 +01:00
})
}
2018-03-09 02:19:50 +01:00
#[inline]
2018-02-26 03:55:07 +01:00
pub fn readany(&mut self) -> Poll<Option<Bytes>, PayloadError> {
if let Some(data) = self.items.pop_front() {
self.len -= data.len();
Ok(Async::Ready(Some(data)))
} else {
match self.poll_stream()? {
Async::Ready(true) => self.readany(),
Async::Ready(false) => Ok(Async::Ready(None)),
Async::NotReady => Ok(Async::NotReady),
}
}
}
2018-03-09 02:19:50 +01:00
#[inline]
pub fn can_read(&mut self, size: usize) -> Poll<Option<bool>, PayloadError> {
2018-02-26 03:55:07 +01:00
if size <= self.len {
2018-03-09 02:19:50 +01:00
Ok(Async::Ready(Some(true)))
} else {
match self.poll_stream()? {
Async::Ready(true) => self.can_read(size),
Async::Ready(false) => Ok(Async::Ready(None)),
Async::NotReady => Ok(Async::NotReady),
}
}
}
2018-03-09 05:39:05 +01:00
#[inline]
pub fn get_chunk(&mut self) -> Poll<Option<&[u8]>, PayloadError> {
if self.items.is_empty() {
match self.poll_stream()? {
Async::Ready(true) => (),
Async::Ready(false) => return Ok(Async::Ready(None)),
Async::NotReady => return Ok(Async::NotReady),
}
}
match self.items.front().map(|c| c.as_ref()) {
Some(chunk) => Ok(Async::Ready(Some(chunk))),
None => Ok(Async::NotReady),
}
}
2018-03-09 02:19:50 +01:00
#[inline]
2018-03-09 14:36:40 +01:00
pub fn read_exact(&mut self, size: usize) -> Poll<Option<Bytes>, PayloadError> {
2018-03-09 02:19:50 +01:00
if size <= self.len {
self.len -= size;
let mut chunk = self.items.pop_front().unwrap();
if size < chunk.len() {
let buf = chunk.split_to(size);
self.items.push_front(chunk);
Ok(Async::Ready(Some(buf)))
2018-04-14 01:02:01 +02:00
} else if size == chunk.len() {
2018-03-09 02:19:50 +01:00
Ok(Async::Ready(Some(chunk)))
2018-04-14 01:02:01 +02:00
} else {
2018-03-09 02:19:50 +01:00
let mut buf = BytesMut::with_capacity(size);
buf.extend_from_slice(&chunk);
while buf.len() < size {
let mut chunk = self.items.pop_front().unwrap();
let rem = cmp::min(size - buf.len(), chunk.len());
buf.extend_from_slice(&chunk.split_to(rem));
if !chunk.is_empty() {
self.items.push_front(chunk);
}
2018-02-26 03:55:07 +01:00
}
2018-03-09 02:19:50 +01:00
Ok(Async::Ready(Some(buf.freeze())))
}
} else {
match self.poll_stream()? {
2018-03-09 14:36:40 +01:00
Async::Ready(true) => self.read_exact(size),
2018-03-09 02:19:50 +01:00
Async::Ready(false) => Ok(Async::Ready(None)),
Async::NotReady => Ok(Async::NotReady),
2018-02-26 03:55:07 +01:00
}
}
2018-03-09 02:19:50 +01:00
}
#[inline]
pub fn drop_payload(&mut self, size: usize) {
if size <= self.len {
self.len -= size;
2018-02-26 03:55:07 +01:00
2018-03-09 02:19:50 +01:00
let mut len = 0;
while len < size {
let mut chunk = self.items.pop_front().unwrap();
2018-04-14 01:02:01 +02:00
let rem = cmp::min(size - len, chunk.len());
2018-03-09 03:19:46 +01:00
len += rem;
2018-03-09 02:19:50 +01:00
if rem < chunk.len() {
chunk.split_to(rem);
self.items.push_front(chunk);
}
}
2018-02-26 03:55:07 +01:00
}
}
2018-02-26 22:58:23 +01:00
pub fn copy(&mut self, size: usize) -> Poll<Option<BytesMut>, PayloadError> {
if size <= self.len {
let mut buf = BytesMut::with_capacity(size);
for chunk in &self.items {
if buf.len() < size {
let rem = cmp::min(size - buf.len(), chunk.len());
buf.extend_from_slice(&chunk[..rem]);
}
if buf.len() == size {
2018-04-14 01:02:01 +02:00
return Ok(Async::Ready(Some(buf)));
2018-02-26 22:58:23 +01:00
}
}
}
match self.poll_stream()? {
Async::Ready(true) => self.copy(size),
Async::Ready(false) => Ok(Async::Ready(None)),
Async::NotReady => Ok(Async::NotReady),
}
}
2018-03-09 14:36:40 +01:00
pub fn read_until(&mut self, line: &[u8]) -> Poll<Option<Bytes>, PayloadError> {
2018-02-26 03:55:07 +01:00
let mut idx = 0;
let mut num = 0;
let mut offset = 0;
let mut found = false;
let mut length = 0;
for no in 0..self.items.len() {
{
let chunk = &self.items[no];
for (pos, ch) in chunk.iter().enumerate() {
if *ch == line[idx] {
idx += 1;
if idx == line.len() {
num = no;
2018-04-14 01:02:01 +02:00
offset = pos + 1;
length += pos + 1;
2018-02-26 03:55:07 +01:00
found = true;
break;
}
} else {
idx = 0
}
}
if !found {
length += chunk.len()
}
}
if found {
let mut buf = BytesMut::with_capacity(length);
if num > 0 {
for _ in 0..num {
buf.extend_from_slice(&self.items.pop_front().unwrap());
}
}
if offset > 0 {
let mut chunk = self.items.pop_front().unwrap();
buf.extend_from_slice(&chunk.split_to(offset));
if !chunk.is_empty() {
self.items.push_front(chunk)
}
}
self.len -= length;
2018-04-14 01:02:01 +02:00
return Ok(Async::Ready(Some(buf.freeze())));
2018-02-26 03:55:07 +01:00
}
}
match self.poll_stream()? {
2018-03-09 14:36:40 +01:00
Async::Ready(true) => self.read_until(line),
2018-02-26 03:55:07 +01:00
Async::Ready(false) => Ok(Async::Ready(None)),
Async::NotReady => Ok(Async::NotReady),
}
}
pub fn readline(&mut self) -> Poll<Option<Bytes>, PayloadError> {
2018-03-09 14:36:40 +01:00
self.read_until(b"\n")
2018-02-26 03:55:07 +01:00
}
pub fn unread_data(&mut self, data: Bytes) {
self.len += data.len();
self.items.push_front(data);
}
#[allow(dead_code)]
2018-02-26 03:55:07 +01:00
pub fn remaining(&mut self) -> Bytes {
2018-04-14 01:02:01 +02:00
self.items
.iter_mut()
2018-02-26 03:55:07 +01:00
.fold(BytesMut::new(), |mut b, c| {
b.extend_from_slice(c);
b
2018-04-14 01:02:01 +02:00
})
.freeze()
2018-02-26 03:55:07 +01:00
}
}
2017-10-23 04:58:50 +02:00
#[cfg(test)]
2017-10-23 06:40:41 +02:00
mod tests {
2017-10-23 04:58:50 +02:00
use super::*;
2017-11-16 07:06:28 +01:00
use failure::Fail;
2017-10-23 04:58:50 +02:00
use futures::future::{lazy, result};
2018-04-14 01:02:01 +02:00
use std::io;
2018-05-25 06:03:16 +02:00
use tokio::runtime::current_thread::Runtime;
2017-10-23 04:58:50 +02:00
2017-10-23 23:08:11 +02:00
#[test]
fn test_error() {
2018-04-14 01:02:01 +02:00
let err: PayloadError =
io::Error::new(io::ErrorKind::Other, "ParseError").into();
2017-10-23 23:08:11 +02:00
assert_eq!(format!("{}", err), "ParseError");
2017-11-16 07:06:28 +01:00
assert_eq!(format!("{}", err.cause().unwrap()), "ParseError");
2017-10-23 23:08:11 +02:00
let err = PayloadError::Incomplete;
2018-04-29 18:09:08 +02:00
assert_eq!(
format!("{}", err),
"A payload reached EOF, but is not complete."
);
2017-10-23 23:08:11 +02:00
}
2017-10-23 04:58:50 +02:00
#[test]
fn test_basic() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (_, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(payload.len, 0);
assert_eq!(Async::NotReady, payload.readany().ok().unwrap());
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
#[test]
fn test_eof() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(Async::NotReady, payload.readany().ok().unwrap());
sender.feed_data(Bytes::from("data"));
sender.feed_eof();
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from("data"))),
payload.readany().ok().unwrap()
);
assert_eq!(payload.len, 0);
assert_eq!(Async::Ready(None), payload.readany().ok().unwrap());
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
#[test]
fn test_err() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(Async::NotReady, payload.readany().ok().unwrap());
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.set_error(PayloadError::Incomplete);
payload.readany().err().unwrap();
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
#[test]
fn test_readany() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.feed_data(Bytes::from("line1"));
sender.feed_data(Bytes::from("line2"));
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from("line1"))),
payload.readany().ok().unwrap()
);
assert_eq!(payload.len, 0);
2018-02-27 01:11:00 +01:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from("line2"))),
payload.readany().ok().unwrap()
);
assert_eq!(payload.len, 0);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
#[test]
fn test_readexactly() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(Async::NotReady, payload.read_exact(2).ok().unwrap());
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.feed_data(Bytes::from("line1"));
sender.feed_data(Bytes::from("line2"));
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from_static(b"li"))),
payload.read_exact(2).ok().unwrap()
);
assert_eq!(payload.len, 3);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from_static(b"ne1l"))),
payload.read_exact(4).ok().unwrap()
);
assert_eq!(payload.len, 4);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.set_error(PayloadError::Incomplete);
payload.read_exact(10).err().unwrap();
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
#[test]
fn test_readuntil() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (mut sender, payload) = Payload::new(false);
let mut payload = PayloadHelper::new(payload);
2017-10-23 04:58:50 +02:00
2018-05-17 21:20:20 +02:00
assert_eq!(Async::NotReady, payload.read_until(b"ne").ok().unwrap());
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.feed_data(Bytes::from("line1"));
sender.feed_data(Bytes::from("line2"));
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from("line"))),
payload.read_until(b"ne").ok().unwrap()
);
assert_eq!(payload.len, 1);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
assert_eq!(
Async::Ready(Some(Bytes::from("1line2"))),
payload.read_until(b"2").ok().unwrap()
);
assert_eq!(payload.len, 0);
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
sender.set_error(PayloadError::Incomplete);
payload.read_until(b"b").err().unwrap();
2017-10-23 04:58:50 +02:00
2018-04-14 01:02:01 +02:00
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 04:58:50 +02:00
}
2017-10-23 05:19:20 +02:00
#[test]
fn test_unread_data() {
2018-05-25 06:03:16 +02:00
Runtime::new()
2018-04-14 01:02:01 +02:00
.unwrap()
2018-05-25 06:03:16 +02:00
.block_on(lazy(|| {
2018-04-14 01:02:01 +02:00
let (_, mut payload) = Payload::new(false);
payload.unread_data(Bytes::from("data"));
assert!(!payload.is_empty());
assert_eq!(payload.len(), 4);
assert_eq!(
Async::Ready(Some(Bytes::from("data"))),
payload.poll().ok().unwrap()
);
let res: Result<(), ()> = Ok(());
result(res)
}))
.unwrap();
2017-10-23 05:19:20 +02:00
}
2017-10-23 04:58:50 +02:00
}