Skip to content

Commit 39f6e55

Browse files
committed
Fix HTTP parsing error in codec.
1 parent cbae391 commit 39f6e55

File tree

1 file changed

+37
-32
lines changed

1 file changed

+37
-32
lines changed

src/codec/http.rs

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ use bytes::BufMut;
1717
#[derive(Copy, Clone, Debug)]
1818
pub struct HttpClientCodec;
1919

20+
fn split_off_http(src: &mut BytesMut) -> Option<BytesMut> {
21+
match src.windows(4).position(|i| i == b"\r\n\r\n") {
22+
Some(p) => Some(src.split_to(p + 4)),
23+
None => None,
24+
}
25+
}
26+
2027
impl Encoder for HttpClientCodec {
2128
type Item = Incoming<(Method, RequestUri)>;
2229
type Error = io::Error;
@@ -43,22 +50,21 @@ impl Decoder for HttpClientCodec {
4350
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
4451
// check if we get a request from hyper
4552
// TODO: this is ineffecient, but hyper does not give us a better way to parse
46-
let (response, bytes_read) = {
47-
let mut reader = BufReader::new(&*src as &[u8]);
48-
let res = match parse_response(&mut reader) {
49-
Err(hyper::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
50-
return Ok(None)
51-
}
52-
Err(hyper::Error::TooLarge) => return Ok(None),
53-
Err(e) => return Err(e.into()),
54-
Ok(r) => r,
55-
};
56-
let (_, _, pos, _) = reader.into_parts();
57-
(res, pos)
58-
};
59-
60-
src.split_to(bytes_read);
61-
Ok(Some(response))
53+
match split_off_http(src) {
54+
Some(buf) => {
55+
let mut reader = BufReader::new(&*src as &[u8]);
56+
let res = match parse_response(&mut reader) {
57+
Err(hyper::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
58+
return Ok(None)
59+
}
60+
Err(hyper::Error::TooLarge) => return Ok(None),
61+
Err(e) => return Err(e.into()),
62+
Ok(r) => r,
63+
};
64+
Ok(Some(res))
65+
}
66+
None => Ok(None),
67+
}
6268
}
6369
}
6470

@@ -87,22 +93,21 @@ impl Decoder for HttpServerCodec {
8793
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
8894
// check if we get a request from hyper
8995
// TODO: this is ineffecient, but hyper does not give us a better way to parse
90-
let (response, bytes_read) = {
91-
let mut reader = BufReader::new(&*src as &[u8]);
92-
let res = match parse_request(&mut reader) {
93-
Err(hyper::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
94-
return Ok(None)
95-
}
96-
Err(hyper::Error::TooLarge) => return Ok(None),
97-
Err(e) => return Err(e.into()),
98-
Ok(r) => r,
99-
};
100-
let (_, _, pos, _) = reader.into_parts();
101-
(res, pos)
102-
};
103-
104-
src.split_to(bytes_read);
105-
Ok(Some(response))
96+
match split_off_http(src) {
97+
Some(buf) => {
98+
let mut reader = BufReader::with_capacity(&*buf as &[u8], buf.len());
99+
let res = match parse_request(&mut reader) {
100+
Err(hyper::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
101+
return Ok(None);
102+
}
103+
Err(hyper::Error::TooLarge) => return Ok(None),
104+
Err(e) => return Err(e.into()),
105+
Ok(r) => r,
106+
};
107+
Ok(Some(res))
108+
}
109+
None => Ok(None),
110+
}
106111
}
107112
}
108113

0 commit comments

Comments
 (0)