diff --git a/src/error.rs b/src/error.rs index 663156e0a9..6912cd3a70 100644 --- a/src/error.rs +++ b/src/error.rs @@ -132,6 +132,17 @@ impl Error { matches!(self.inner.kind, Kind::Parse(_)) } + /// Returns true if this was an HTTP parse error caused by a message that was too large. + pub fn is_parse_too_large(&self) -> bool { + matches!(self.inner.kind, Kind::Parse(Parse::TooLarge)) + } + + /// Returns true if this was an HTTP parse error caused by an invalid response status code or + /// reason phrase. + pub fn is_parse_status(&self) -> bool { + matches!(self.inner.kind, Kind::Parse(Parse::Status)) + } + /// Returns true if this error was caused by user code. pub fn is_user(&self) -> bool { matches!(self.inner.kind, Kind::User(_)) diff --git a/tests/client.rs b/tests/client.rs index d22f8cf2ca..52747a30c6 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -907,6 +907,83 @@ test! { } +test! { + name: client_error_parse_too_large, + + server: + expected: "\ + GET /err HTTP/1.1\r\n\ + host: {addr}\r\n\ + \r\n\ + ", + reply: { + let long_header = std::iter::repeat("A").take(500_000).collect::(); + format!("\ + HTTP/1.1 200 OK\r\n\ + {}: {}\r\n\ + \r\n\ + ", + long_header, + long_header, + ) + }, + + client: + request: { + method: GET, + url: "http://{addr}/err", + }, + // should get a Parse(TooLarge) error + error: |err| err.is_parse() && err.is_parse_too_large(), + +} + +test! { + name: client_error_parse_status_out_of_range, + + server: + expected: "\ + GET /err HTTP/1.1\r\n\ + host: {addr}\r\n\ + \r\n\ + ", + reply: "\ + HTTP/1.1 001 OK\r\n\ + \r\n\ + ", + + client: + request: { + method: GET, + url: "http://{addr}/err", + }, + // should get a Parse(Status) error + error: |err| err.is_parse() && err.is_parse_status(), +} + +test! { + name: client_error_parse_status_syntactically_invalid, + + server: + expected: "\ + GET /err HTTP/1.1\r\n\ + host: {addr}\r\n\ + \r\n\ + ", + reply: "\ + HTTP/1.1 1 OK\r\n\ + \r\n\ + ", + + client: + request: { + method: GET, + url: "http://{addr}/err", + }, + // should get a Parse(Status) error + error: |err| err.is_parse() && err.is_parse_status(), +} + test! { name: client_100_continue,