|
|
|
@ -179,6 +179,7 @@ pub fn parse_headers(mut input: &[u8]) -> IResult<&[u8], HashMap<String, String>
|
|
|
|
|
|
|
|
|
|
fn parse_header_value(buf: &[u8]) -> IResult<&[u8], &[u8]> {
|
|
|
|
|
let mut end_pos = 0;
|
|
|
|
|
let mut trail_spaces = 0;
|
|
|
|
|
let mut idx = 0;
|
|
|
|
|
while idx < buf.len() {
|
|
|
|
|
match buf[idx] {
|
|
|
|
@ -193,12 +194,16 @@ fn parse_header_value(buf: &[u8]) -> IResult<&[u8], &[u8]> {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
return Ok((&buf[end_pos..], &buf[..end_pos]));
|
|
|
|
|
return Ok((&buf[(end_pos + trail_spaces)..], &buf[..end_pos]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
b' ' | b'\t' | b'\r' => {}
|
|
|
|
|
b' ' | b'\t' => {
|
|
|
|
|
trail_spaces += 1;
|
|
|
|
|
}
|
|
|
|
|
b'\r' => {}
|
|
|
|
|
b => {
|
|
|
|
|
trail_spaces = 0;
|
|
|
|
|
if !is_header_value(b) {
|
|
|
|
|
return Err(Err::Incomplete(Needed::Size(1)));
|
|
|
|
|
}
|
|
|
|
@ -237,6 +242,28 @@ mod tests {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_request_trail_space_header() {
|
|
|
|
|
let buf: &[u8] = "REGISTER sip:sip.cybercity.dk SIP/2.0\r\n\
|
|
|
|
|
From: <sip:voi18063@sip.cybercity.dk>;tag=903df0a\r\n\
|
|
|
|
|
To: <sip:voi18063@sip.cybercity.dk>\r\n\
|
|
|
|
|
Content-Length: 0 \r\n\
|
|
|
|
|
\r\n"
|
|
|
|
|
.as_bytes();
|
|
|
|
|
|
|
|
|
|
match sip_parse_request(buf) {
|
|
|
|
|
Ok((_, req)) => {
|
|
|
|
|
assert_eq!(req.method, "REGISTER");
|
|
|
|
|
assert_eq!(req.path, "sip:sip.cybercity.dk");
|
|
|
|
|
assert_eq!(req.version, "SIP/2.0");
|
|
|
|
|
assert_eq!(req.headers["Content-Length"], "0");
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
assert!(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_response() {
|
|
|
|
|
let buf: &[u8] = "SIP/2.0 401 Unauthorized\r\n\
|
|
|
|
|