mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-28 09:42:40 +01:00
simplify client decoder
This commit is contained in:
parent
6297fe0d41
commit
03ad9a3105
@ -45,9 +45,9 @@ rust-tls = ["rustls", "actix-net/rust-tls"]
|
||||
|
||||
[dependencies]
|
||||
actix = "0.7.5"
|
||||
#actix-net = "0.2.0"
|
||||
#actix-net = { git="https://github.com/actix/actix-net.git" }
|
||||
actix-net = { path="../actix-net" }
|
||||
#actix-net = "0.2.2"
|
||||
actix-net = { git="https://github.com/actix/actix-net.git" }
|
||||
#actix-net = { path="../actix-net" }
|
||||
|
||||
base64 = "0.9"
|
||||
bitflags = "1.0"
|
||||
|
@ -40,11 +40,12 @@ where
|
||||
.into_future()
|
||||
.map_err(|(e, _)| SendRequestError::from(e))
|
||||
.and_then(|(item, framed)| {
|
||||
if let Some(item) = item {
|
||||
let mut res = item.into_item().unwrap();
|
||||
if let Some(res) = item {
|
||||
match framed.get_codec().message_type() {
|
||||
h1::MessageType::None => release_connection(framed),
|
||||
_ => *res.payload.borrow_mut() = Some(Payload::stream(framed)),
|
||||
_ => {
|
||||
*res.payload.borrow_mut() = Some(Payload::stream(framed))
|
||||
}
|
||||
}
|
||||
ok(res)
|
||||
} else {
|
||||
@ -92,21 +93,14 @@ where
|
||||
&& !self.framed.as_ref().unwrap().is_write_buf_full()
|
||||
{
|
||||
match self.body.as_mut().unwrap().poll_next()? {
|
||||
Async::Ready(None) => {
|
||||
Async::Ready(item) => {
|
||||
self.flushed = false;
|
||||
self.framed
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.start_send(h1::Message::Chunk(None))?;
|
||||
.force_send(h1::Message::Chunk(item))?;
|
||||
break;
|
||||
}
|
||||
Async::Ready(Some(chunk)) => {
|
||||
self.flushed = false;
|
||||
self.framed
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.start_send(h1::Message::Chunk(Some(chunk)))?;
|
||||
}
|
||||
Async::NotReady => body_ready = false,
|
||||
}
|
||||
}
|
||||
|
@ -178,17 +178,13 @@ impl ClientCodecInner {
|
||||
}
|
||||
|
||||
impl Decoder for ClientCodec {
|
||||
type Item = Message<ClientResponse>;
|
||||
type Item = ClientResponse;
|
||||
type Error = ParseError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
if self.inner.payload.is_some() {
|
||||
Ok(match self.inner.payload.as_mut().unwrap().decode(src)? {
|
||||
Some(PayloadItem::Chunk(chunk)) => Some(Message::Chunk(Some(chunk))),
|
||||
Some(PayloadItem::Eof) => Some(Message::Chunk(None)),
|
||||
None => None,
|
||||
})
|
||||
} else if let Some((req, payload)) = self.inner.decoder.decode(src)? {
|
||||
debug_assert!(!self.inner.payload.is_some(), "Payload decoder is set");
|
||||
|
||||
if let Some((req, payload)) = self.inner.decoder.decode(src)? {
|
||||
self.inner
|
||||
.flags
|
||||
.set(Flags::HEAD, req.inner.method == Method::HEAD);
|
||||
@ -204,7 +200,7 @@ impl Decoder for ClientCodec {
|
||||
self.inner.flags.insert(Flags::STREAM);
|
||||
}
|
||||
};
|
||||
Ok(Some(Message::Item(req)))
|
||||
Ok(Some(req))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@ -216,7 +212,7 @@ impl Decoder for ClientPayloadCodec {
|
||||
type Error = PayloadError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
assert!(
|
||||
debug_assert!(
|
||||
self.inner.payload.is_some(),
|
||||
"Payload decoder is not specified"
|
||||
);
|
||||
|
@ -64,7 +64,7 @@ enum State<S: Service> {
|
||||
None,
|
||||
ServiceCall(S::Future),
|
||||
SendResponse(Option<(Message<Response>, Body)>),
|
||||
SendPayload(Option<BodyStream>, Option<Message<Response>>),
|
||||
SendPayload(BodyStream),
|
||||
}
|
||||
|
||||
impl<S: Service> State<S> {
|
||||
@ -204,21 +204,23 @@ where
|
||||
// send respons
|
||||
State::SendResponse(ref mut item) => {
|
||||
let (msg, body) = item.take().expect("SendResponse is empty");
|
||||
match self.framed.as_mut().unwrap().start_send(msg) {
|
||||
let framed = self.framed.as_mut().unwrap();
|
||||
match framed.start_send(msg) {
|
||||
Ok(AsyncSink::Ready) => {
|
||||
self.flags.set(
|
||||
Flags::KEEPALIVE,
|
||||
self.framed.as_mut().unwrap().get_codec().keepalive(),
|
||||
);
|
||||
self.flags
|
||||
.set(Flags::KEEPALIVE, framed.get_codec().keepalive());
|
||||
self.flags.remove(Flags::FLUSHED);
|
||||
match body {
|
||||
Body::Empty => Some(State::None),
|
||||
Body::Binary(mut bin) => Some(State::SendPayload(
|
||||
None,
|
||||
Some(Message::Chunk(Some(bin.take()))),
|
||||
)),
|
||||
Body::Streaming(stream) => {
|
||||
Some(State::SendPayload(Some(stream), None))
|
||||
Some(State::SendPayload(stream))
|
||||
}
|
||||
Body::Binary(mut bin) => {
|
||||
self.flags.remove(Flags::FLUSHED);
|
||||
framed
|
||||
.force_send(Message::Chunk(Some(bin.take())))?;
|
||||
framed.force_send(Message::Chunk(None))?;
|
||||
Some(State::None)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,51 +237,28 @@ where
|
||||
}
|
||||
}
|
||||
// Send payload
|
||||
State::SendPayload(ref mut stream, ref mut bin) => {
|
||||
println!("SEND payload");
|
||||
if let Some(item) = bin.take() {
|
||||
State::SendPayload(ref mut stream) => {
|
||||
let mut framed = self.framed.as_mut().unwrap();
|
||||
if framed.is_
|
||||
match self.framed.as_mut().unwrap().start_send(item) {
|
||||
Ok(AsyncSink::Ready) => {
|
||||
self.flags.remove(Flags::FLUSHED);
|
||||
}
|
||||
Ok(AsyncSink::NotReady(item)) => {
|
||||
*bin = Some(item);
|
||||
return Ok(());
|
||||
}
|
||||
Err(err) => return Err(DispatchError::Io(err)),
|
||||
}
|
||||
}
|
||||
if let Some(ref mut stream) = stream {
|
||||
match stream.poll() {
|
||||
Ok(Async::Ready(Some(item))) => match self
|
||||
.framed
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.start_send(Message::Chunk(Some(item)))
|
||||
{
|
||||
Ok(AsyncSink::Ready) => {
|
||||
loop {
|
||||
if !framed.is_write_buf_full() {
|
||||
match stream.poll().map_err(|_| DispatchError::Unknown)? {
|
||||
Async::Ready(Some(item)) => {
|
||||
self.flags.remove(Flags::FLUSHED);
|
||||
framed.force_send(Message::Chunk(Some(item)))?;
|
||||
continue;
|
||||
}
|
||||
Ok(AsyncSink::NotReady(msg)) => {
|
||||
*bin = Some(msg);
|
||||
return Ok(());
|
||||
Async::Ready(None) => {
|
||||
self.flags.remove(Flags::FLUSHED);
|
||||
framed.force_send(Message::Chunk(None))?;
|
||||
}
|
||||
Err(err) => return Err(DispatchError::Io(err)),
|
||||
},
|
||||
Ok(Async::Ready(None)) => Some(State::SendPayload(
|
||||
None,
|
||||
Some(Message::Chunk(None)),
|
||||
)),
|
||||
Ok(Async::NotReady) => return Ok(()),
|
||||
// Err(err) => return Err(DispatchError::Io(err)),
|
||||
Err(_) => return Err(DispatchError::Unknown),
|
||||
Async::NotReady => return Ok(()),
|
||||
}
|
||||
} else {
|
||||
Some(State::None)
|
||||
return Ok(());
|
||||
}
|
||||
break;
|
||||
}
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,15 +33,6 @@ pub enum Message<T> {
|
||||
Chunk(Option<Bytes>),
|
||||
}
|
||||
|
||||
impl<T> Message<T> {
|
||||
pub fn into_item(self) -> Option<T> {
|
||||
match self {
|
||||
Message::Item(item) => Some(item),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Message<T> {
|
||||
fn from(item: T) -> Self {
|
||||
Message::Item(item)
|
||||
|
@ -172,10 +172,7 @@ where
|
||||
{
|
||||
fut: Box<
|
||||
Future<
|
||||
Item = (
|
||||
Option<h1::Message<ClientResponse>>,
|
||||
Framed<T, h1::ClientCodec>,
|
||||
),
|
||||
Item = (Option<ClientResponse>, Framed<T, h1::ClientCodec>),
|
||||
Error = ClientError,
|
||||
>,
|
||||
>,
|
||||
@ -196,8 +193,7 @@ where
|
||||
let (item, framed) = try_ready!(self.fut.poll());
|
||||
|
||||
let res = match item {
|
||||
Some(h1::Message::Item(res)) => res,
|
||||
Some(h1::Message::Chunk(_)) => unreachable!(),
|
||||
Some(res) => res,
|
||||
None => return Err(ClientError::Disconnected),
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user