Support STREAMING-AWS4-HMAC-SHA256-PAYLOAD (#64) #156
1 changed files with 19 additions and 11 deletions
|
@ -192,35 +192,42 @@ where
|
||||||
let mut this = self.project();
|
let mut this = self.project();
|
||||||
|
|
||||||
macro_rules! try_parse {
|
macro_rules! try_parse {
|
||||||
($expr:expr) => {
|
($eof:expr, $expr:expr) => {
|
||||||
match $expr {
|
match $expr {
|
||||||
Ok(value) => Ok(value),
|
Ok(value) => Ok(value),
|
||||||
Err(nom::Err::Incomplete(_)) => continue,
|
Err(nom::Err::Incomplete(_)) => {
|
||||||
|
if $eof {
|
||||||
|
return Poll::Ready(Some(Err(SignedPayloadStreamError::message(
|
||||||
|
"Unexpected EOF",
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(e),
|
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => Err(e),
|
||||||
}?
|
}?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match futures::ready!(this.stream.as_mut().poll_next(cx)) {
|
let eof = match futures::ready!(this.stream.as_mut().poll_next(cx)) {
|
||||||
Some(Ok(bytes)) => {
|
Some(Ok(bytes)) => {
|
||||||
|
log::debug!("Received: {:?}", bytes);
|
||||||
this.buf.extend(bytes);
|
this.buf.extend(bytes);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
Some(Err(e)) => return Poll::Ready(Some(Err(SignedPayloadStreamError::Stream(e)))),
|
Some(Err(e)) => return Poll::Ready(Some(Err(SignedPayloadStreamError::Stream(e)))),
|
||||||
None => {
|
None => {
|
||||||
|
log::debug!("Buf: {:?}", this.buf);
|
||||||
KokaKiwi marked this conversation as resolved
Outdated
|
|||||||
if this.buf.is_empty() {
|
if this.buf.is_empty() {
|
||||||
return Poll::Ready(None);
|
return Poll::Ready(None);
|
||||||
} else {
|
|
||||||
return Poll::Ready(Some(Err(SignedPayloadStreamError::message(
|
|
||||||
"Unexpected EOF",
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let input: &[u8] = this.buf;
|
let input: &[u8] = this.buf;
|
||||||
|
|
||||||
let (input, header) = try_parse!(payload::Header::parse(input));
|
let (input, header) = try_parse!(eof, payload::Header::parse(input));
|
||||||
|
|
||||||
// 0-sized chunk is the last
|
// 0-sized chunk is the last
|
||||||
if header.size == 0 {
|
if header.size == 0 {
|
||||||
|
@ -228,8 +235,9 @@ where
|
||||||
return Poll::Ready(None);
|
return Poll::Ready(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (input, data) = try_parse!(take::<_, _, nom::error::Error<_>>(header.size)(input));
|
let (input, data) =
|
||||||
KokaKiwi marked this conversation as resolved
Outdated
trinity-1686a
commented
this bit has an invalid edge case : by cutting the stream just before a new chunk header, an attacker can truncate the file without it being rejected. Getting here (inner stream returns None and this.buf is empy) is either such a truncation, or a call to SignedPayloadStream::poll_next after it returned Ok(Ready(None)) once, which is a contract error ( this bit has an invalid edge case : by cutting the stream just before a new chunk header, an attacker can truncate the file without it being rejected. Getting here (inner stream returns None and this.buf is empy) is either such a truncation, or a call to SignedPayloadStream::poll_next after it returned Ok(Ready(None)) once, which is a contract error ([`Ok(Ready(None)) means that the stream has terminated, and poll_next should not be invoked again`](https://docs.rs/futures/0.2.0/futures/stream/trait.Stream.html#return-value)), so this check and return can be safely removed
|
|||||||
let (input, _) = try_parse!(tag::<_, _, nom::error::Error<_>>("\r\n")(input));
|
try_parse!(eof, take::<_, _, nom::error::Error<_>>(header.size)(input));
|
||||||
|
let (input, _) = try_parse!(eof, tag::<_, _, nom::error::Error<_>>("\r\n")(input));
|
||||||
|
|
||||||
let data = Bytes::from(data.to_vec());
|
let data = Bytes::from(data.to_vec());
|
||||||
let data_sha256sum = sha256sum(&data);
|
let data_sha256sum = sha256sum(&data);
|
||||||
|
|
Loading…
Reference in a new issue
What if the payload input stream is interrupted in the middle? Do we take care of exiting the infinite loop and return an error?