seanmonstar / httparse

A push parser for the HTTP 1.x protocol in Rust.
https://docs.rs/httparse
Apache License 2.0
584 stars 114 forks source link

Headers lost on a Partial parse #102

Closed rcoh closed 3 years ago

rcoh commented 3 years ago

I'm not sure if this is worth fixing, but it will almost certainly break some things (it broke our tests at least):

In 1.4, parsing a request would extract headers if the string was terminated with a single newline, however, that behavior changed in 1.5 (now two newlines are required). A reproducer is below:

    #[test]
    fn test_httparse() {
        let works_1_4_1 = b"GET /?Param2=value2&Param1=value1 HTTP/1.1\nHost:example.com\n";
        let works_1_5 = b"GET /?Param2=value2&Param1=value1 HTTP/1.1\nHost:example.com\n\n";
        let mut headers = [httparse::EMPTY_HEADER; 64];
        let n_headers =
            |req: httparse::Request| req.headers.iter().filter(|h| !h.name.is_empty()).count();
        {
            // test for 1.4.1
            let mut req = httparse::Request::new(&mut headers);
            let _ = req.parse(works_1_4_1).unwrap();
            assert_eq!(n_headers(req), 1, "failed on 1.4.1 test");
        }
        {
            // test for 1.5
            let mut req = httparse::Request::new(&mut headers);
            let _ = req.parse(works_1_5).unwrap();
            assert_eq!(n_headers(req), 1);
        }
    }
seanmonstar commented 3 years ago

Thanks for reporting! This is a bug that snuck in, fix is in #103. I'll release 1.5.1 shortly.