Skip to content
This repository was archived by the owner on Sep 4, 2024. It is now read-only.

Commit 7640a4b

Browse files
committed
simple_http: split HttpParseError into several variants
There is only one case left, which probably should not be an error at all.
1 parent 36708d6 commit 7640a4b

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

src/simple_http.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::net::TcpStream;
1010
use std::net::{SocketAddr, ToSocketAddrs};
1111
use std::sync::{Arc, Mutex};
1212
use std::time::{Duration, Instant};
13-
use std::{error, fmt, io, net, thread};
13+
use std::{error, fmt, io, net, num, thread};
1414

1515
use base64;
1616
use serde;
@@ -157,12 +157,21 @@ impl SimpleHttpTransport {
157157

158158
// Parse first HTTP response header line
159159
let http_response = get_line(&mut reader, request_deadline)?;
160-
if http_response.len() < 12 || !http_response.starts_with("HTTP/1.1 ") {
161-
return Err(Error::HttpParseError);
160+
if http_response.len() < 12 {
161+
return Err(Error::HttpResponseTooShort { actual: http_response.len(), needed: 12 });
162+
}
163+
if !http_response.starts_with("HTTP/1.1 ") {
164+
return Err(Error::HttpResponseBadHello {
165+
actual: String::from_utf8_lossy(&http_response.as_bytes()[0..9]).into(),
166+
expected: "HTTP/1.1 ".into(),
167+
});
162168
}
163169
let response_code = match http_response[9..12].parse::<u16>() {
164170
Ok(n) => n,
165-
Err(_) => return Err(Error::HttpParseError),
171+
Err(e) => return Err(Error::HttpResponseBadStatus(
172+
String::from_utf8_lossy(&http_response.as_bytes()[9..12]).into(),
173+
e,
174+
)),
166175
};
167176

168177
// Parse response header fields
@@ -180,7 +189,7 @@ impl SimpleHttpTransport {
180189
line[CONTENT_LENGTH.len()..]
181190
.trim()
182191
.parse::<usize>()
183-
.map_err(|_| Error::HttpParseError)?,
192+
.map_err(|e| Error::HttpResponseBadContentLength(line[CONTENT_LENGTH.len()..].into(), e))?
184193
);
185194
}
186195
}
@@ -224,6 +233,24 @@ pub enum Error {
224233
},
225234
/// An error occurred on the socket layer.
226235
SocketError(io::Error),
236+
/// The HTTP response was too short to even fit a HTTP 1.1 header
237+
HttpResponseTooShort {
238+
/// The total length of the response
239+
actual: usize,
240+
/// Minimum length we can parse
241+
needed: usize,
242+
},
243+
/// The HTTP response did not start with HTTP/1.1
244+
HttpResponseBadHello {
245+
/// Actual HTTP-whatever string
246+
actual: String,
247+
/// The hello string of the HTTP version we support
248+
expected: String,
249+
},
250+
/// Could not parse the status value as a number
251+
HttpResponseBadStatus(String, num::ParseIntError),
252+
/// Could not parse the status value as a number
253+
HttpResponseBadContentLength(String, num::ParseIntError),
227254
/// The HTTP header of the response couldn't be parsed.
228255
HttpParseError,
229256
/// Unexpected HTTP error code (non-200).
@@ -252,6 +279,18 @@ impl fmt::Display for Error {
252279
ref reason,
253280
} => write!(f, "invalid URL '{}': {}", url, reason),
254281
Error::SocketError(ref e) => write!(f, "Couldn't connect to host: {}", e),
282+
Error::HttpResponseTooShort { ref actual, ref needed } => {
283+
write!(f, "HTTP response too short: length {}, needed {}.", actual, needed)
284+
},
285+
Error::HttpResponseBadHello { ref actual, ref expected } => {
286+
write!(f, "HTTP response started with `{}`; expected `{}`.", actual, expected)
287+
},
288+
Error::HttpResponseBadStatus(ref status, ref err) => {
289+
write!(f, "HTTP response had bad status code `{}`: {}.", status, err)
290+
},
291+
Error::HttpResponseBadContentLength(ref len, ref err) => {
292+
write!(f, "HTTP response had bad content length `{}`: {}.", len, err)
293+
},
255294
Error::HttpParseError => f.write_str("Couldn't parse response header."),
256295
Error::HttpErrorCode(c) => write!(f, "unexpected HTTP code: {}", c),
257296
Error::Timeout => f.write_str("Didn't receive response data in time, timed out."),
@@ -268,6 +307,10 @@ impl error::Error for Error {
268307
InvalidUrl {
269308
..
270309
}
310+
| HttpResponseTooShort { .. }
311+
| HttpResponseBadHello { .. }
312+
| HttpResponseBadStatus(..)
313+
| HttpResponseBadContentLength(..)
271314
| HttpParseError
272315
| HttpErrorCode(_)
273316
| Timeout => None,

0 commit comments

Comments
 (0)