micro-http: unsigned Content-Length...
...and a bunch of fixes for unchecked unsigned arithmetic in connection.rs. Added more unit tests too that exercise failure cases for over/underflows in mathematic operations. Fixes #1977 Signed-off-by: Alexandra Iordache <aghecen@amazon.com> Signed-off-by: YUAN LYU <lyuyuan92@gmail.com>
This commit is contained in:
committed by
Adrian Catangiu
parent
48b8f179c8
commit
88de0ed16b
@@ -74,7 +74,7 @@ impl Header {
|
||||
pub struct Headers {
|
||||
/// The `Content-Length` header field tells us how many bytes we need to receive
|
||||
/// from the source after the headers.
|
||||
content_length: i32,
|
||||
content_length: u32,
|
||||
/// The `Expect` header field is set when the headers contain the entry "Expect: 100-continue".
|
||||
/// This means that, per HTTP/1.1 specifications, we must send a response with the status code
|
||||
/// 100 after we have received the headers in order to receive the body of the request. This
|
||||
@@ -134,7 +134,7 @@ impl Headers {
|
||||
}
|
||||
if let Ok(head) = Header::try_from(entry[0].as_bytes()) {
|
||||
match head {
|
||||
Header::ContentLength => match entry[1].trim().parse::<i32>() {
|
||||
Header::ContentLength => match entry[1].trim().parse::<u32>() {
|
||||
Ok(content_length) => {
|
||||
self.content_length = content_length;
|
||||
Ok(())
|
||||
@@ -180,7 +180,7 @@ impl Headers {
|
||||
}
|
||||
|
||||
/// Returns the content length of the body.
|
||||
pub fn content_length(&self) -> i32 {
|
||||
pub fn content_length(&self) -> u32 {
|
||||
self.content_length
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
impl Headers {
|
||||
pub fn new(content_length: i32, expect: bool, chunked: bool) -> Self {
|
||||
pub fn new(content_length: u32, expect: bool, chunked: bool) -> Self {
|
||||
Self {
|
||||
content_length,
|
||||
expect,
|
||||
@@ -480,6 +480,12 @@ mod tests {
|
||||
assert!(header
|
||||
.parse_header_line(b"Accept: application/json-patch")
|
||||
.is_err());
|
||||
|
||||
// Invalid content length.
|
||||
assert_eq!(
|
||||
header.parse_header_line(b"Content-Length: -1"),
|
||||
Err(RequestError::InvalidHeader)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -16,6 +16,10 @@ pub mod ascii {
|
||||
/// Errors associated with parsing the HTTP Request from a u8 slice.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum RequestError {
|
||||
/// No request was pending while the request body was being parsed.
|
||||
BodyWithoutPendingRequest,
|
||||
/// No request was pending while the request headers were being parsed.
|
||||
HeadersWithoutPendingRequest,
|
||||
/// The HTTP Method is not supported or it is invalid.
|
||||
InvalidHttpMethod(&'static str),
|
||||
/// Request URI is invalid.
|
||||
@@ -37,6 +41,14 @@ pub enum RequestError {
|
||||
impl Display for RequestError {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
match self {
|
||||
Self::BodyWithoutPendingRequest => write!(
|
||||
f,
|
||||
"No request was pending while the request body was being parsed."
|
||||
),
|
||||
Self::HeadersWithoutPendingRequest => write!(
|
||||
f,
|
||||
"No request was pending while the request headers were being parsed."
|
||||
),
|
||||
Self::InvalidHttpMethod(inner) => write!(f, "Invalid HTTP Method: {}", inner),
|
||||
Self::InvalidUri(inner) => write!(f, "Invalid URI: {}", inner),
|
||||
Self::InvalidHttpVersion(inner) => write!(f, "Invalid HTTP Version: {}", inner),
|
||||
@@ -322,6 +334,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_display_request_error() {
|
||||
assert_eq!(
|
||||
format!("{}", RequestError::BodyWithoutPendingRequest),
|
||||
"No request was pending while the request body was being parsed."
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", RequestError::HeadersWithoutPendingRequest),
|
||||
"No request was pending while the request headers were being parsed."
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", RequestError::InvalidHeader),
|
||||
"Invalid header."
|
||||
|
||||
Reference in New Issue
Block a user