Skip to content

Commit a3be110

Browse files
committed
feat(body): change Payload::Data to be a Buf
Closes #1508 BREAKING CHANGE: Each payload chunk must implement `Buf`, instead of just `AsRef<[u8]>`.
1 parent dfa7e17 commit a3be110

File tree

6 files changed

+34
-30
lines changed

6 files changed

+34
-30
lines changed

src/body.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use std::borrow::Cow;
1818
use std::fmt;
1919

20-
use bytes::Bytes;
20+
use bytes::{Buf, Bytes};
2121
use futures::{Async, Future, Poll, Stream};
2222
use futures::sync::{mpsc, oneshot};
2323
use h2;
@@ -34,7 +34,7 @@ type BodySender = mpsc::Sender<Result<Chunk, ::Error>>;
3434
/// don't need to customize a send stream for your own application.
3535
pub trait Payload: Send + 'static {
3636
/// A buffer of bytes representing a single chunk of a body.
37-
type Data: AsRef<[u8]> + Send;
37+
type Data: Buf + Send;
3838

3939
/// The error type of this stream.
4040
type Error: Into<Box<::std::error::Error + Send + Sync>>;

src/chunk.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::fmt;
22

3-
use bytes::Bytes;
3+
use bytes::{Buf, Bytes};
44
use h2::ReleaseCapacity;
55

66
/// A piece of a message body.
@@ -53,6 +53,23 @@ impl Chunk {
5353
}
5454
}
5555

56+
impl Buf for Chunk {
57+
#[inline]
58+
fn remaining(&self) -> usize {
59+
self.bytes.len()
60+
}
61+
62+
#[inline]
63+
fn bytes(&self) -> &[u8] {
64+
&self.bytes
65+
}
66+
67+
#[inline]
68+
fn advance(&mut self, cnt: usize) {
69+
self.bytes.advance(cnt);
70+
}
71+
}
72+
5673
impl From<Vec<u8>> for Chunk {
5774
#[inline]
5875
fn from(v: Vec<u8>) -> Chunk {

src/client/conn.rs

-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,6 @@ impl<T: Send, B: Send> AssertSend for Connection<T, B>
626626
where
627627
T: AsyncRead + AsyncWrite + Send + 'static,
628628
B: Payload + 'static,
629-
B::Data: Send + 'static,
630629
{}
631630

632631
#[doc(hidden)]

src/proto/h1/conn.rs

+8-19
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ use std::fmt;
22
use std::io::{self};
33
use std::marker::PhantomData;
44

5-
use bytes::Bytes;
5+
use bytes::{Buf, Bytes};
66
use futures::{Async, AsyncSink, Poll, StartSend};
77
use futures::task::Task;
88
use http::{Method, Version};
99
use tokio_io::{AsyncRead, AsyncWrite};
1010

1111
use ::Chunk;
1212
use proto::{BodyLength, Decode, Http1Transaction, MessageHead};
13-
use super::io::{Cursor, Buffered};
13+
use super::io::{Buffered};
1414
use super::{EncodedBuf, Encoder, Decoder};
1515

1616

@@ -22,25 +22,14 @@ use super::{EncodedBuf, Encoder, Decoder};
2222
/// determine if this connection can be kept alive after the message,
2323
/// or if it is complete.
2424
pub(crate) struct Conn<I, B, T> {
25-
io: Buffered<I, EncodedBuf<Cursor<B>>>,
25+
io: Buffered<I, EncodedBuf<B>>,
2626
state: State,
2727
_marker: PhantomData<T>
2828
}
2929

30-
/*
31-
impl<I, B> Conn<I, B, ClientTransaction>
32-
where I: AsyncRead + AsyncWrite,
33-
B: AsRef<[u8]>,
34-
{
35-
pub fn new_client(io: I) -> Conn<I, B, ClientTransaction> {
36-
Conn::new(io)
37-
}
38-
}
39-
*/
40-
4130
impl<I, B, T> Conn<I, B, T>
4231
where I: AsyncRead + AsyncWrite,
43-
B: AsRef<[u8]>,
32+
B: Buf,
4433
T: Http1Transaction,
4534
{
4635
pub fn new(io: I) -> Conn<I, B, T> {
@@ -488,7 +477,7 @@ where I: AsyncRead + AsyncWrite,
488477
if !self.can_buffer_body() {
489478
if let Async::NotReady = self.flush()? {
490479
// if chunk is Some(&[]), aka empty, whatever, just skip it
491-
if chunk.as_ref().map(|c| c.as_ref().is_empty()).unwrap_or(false) {
480+
if chunk.as_ref().map(|c| c.remaining() == 0).unwrap_or(false) {
492481
return Ok(AsyncSink::Ready);
493482
} else {
494483
return Ok(AsyncSink::NotReady(chunk));
@@ -499,11 +488,11 @@ where I: AsyncRead + AsyncWrite,
499488
let state = match self.state.writing {
500489
Writing::Body(ref mut encoder) => {
501490
if let Some(chunk) = chunk {
502-
if chunk.as_ref().is_empty() {
491+
if chunk.remaining() == 0 {
503492
return Ok(AsyncSink::Ready);
504493
}
505494

506-
let encoded = encoder.encode(Cursor::new(chunk));
495+
let encoded = encoder.encode(chunk);
507496
self.io.buffer(encoded);
508497

509498
if encoder.is_eof() {
@@ -612,7 +601,7 @@ where I: AsyncRead + AsyncWrite,
612601
}
613602
}
614603

615-
impl<I, B: AsRef<[u8]>, T> fmt::Debug for Conn<I, B, T> {
604+
impl<I, B: Buf, T> fmt::Debug for Conn<I, B, T> {
616605
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617606
f.debug_struct("Conn")
618607
.field("state", &self.state)

src/proto/h1/dispatch.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bytes::Bytes;
1+
use bytes::{Buf, Bytes};
22
use futures::{Async, Future, Poll, Stream};
33
use http::{Request, Response, StatusCode};
44
use tokio_io::{AsyncRead, AsyncWrite};
@@ -241,7 +241,7 @@ where
241241
if self.conn.can_write_body() {
242242
self.conn.write_body(Some(chunk)).map_err(::Error::new_body_write)?;
243243
// This allows when chunk is `None`, or `Some([])`.
244-
} else if chunk.as_ref().len() == 0 {
244+
} else if chunk.remaining() == 0 {
245245
// ok
246246
} else {
247247
warn!("unexpected chunk when body cannot write");

src/proto/h2/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use http::HeaderMap;
55
use http::header::{CONNECTION, TRANSFER_ENCODING};
66

77
use ::body::Payload;
8-
use ::proto::h1::Cursor;
98

109
mod client;
1110
mod server;
@@ -74,11 +73,11 @@ where
7473
let is_eos = self.stream.is_end_stream();
7574
trace!(
7675
"send body chunk: {} bytes, eos={}",
77-
chunk.as_ref().len(),
76+
chunk.remaining(),
7877
is_eos,
7978
);
8079

81-
let buf = SendBuf(Some(Cursor::new(chunk)));
80+
let buf = SendBuf(Some(chunk));
8281
self.body_tx.send_data(buf, is_eos)
8382
.map_err(::Error::new_body_write)?;
8483

@@ -104,9 +103,9 @@ where
104103
}
105104
}
106105

107-
struct SendBuf<B>(Option<Cursor<B>>);
106+
struct SendBuf<B>(Option<B>);
108107

109-
impl<B: AsRef<[u8]>> Buf for SendBuf<B> {
108+
impl<B: Buf> Buf for SendBuf<B> {
110109
#[inline]
111110
fn remaining(&self) -> usize {
112111
self.0

0 commit comments

Comments
 (0)