seanmonstar / httparse

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

Add dynamic headers support #51

Open earthengine opened 5 years ago

earthengine commented 5 years ago

This work is an experimential support for a better API in regards to #18 .

The design is not yet ideal: it requires the user to call get_request on the same buffer as the parse call. But it works.

Now we can write

let buf = b"GET /404 HTTP/1.1\r\nHost:";
let mut req = httparse::DynRequest::new(None);
let res = req.parse(buf).unwrap();
if res.is_partial() {
    // get a snapshot with statically allocated headers
    let req = req.get_request(buf);
    match req.path {
        Some(ref path) => {
            // check router for path.
            // /404 doesn't exist? we could stop parsing
        },
        None => {
            // must read more and parse again
        }
    }
}

without knowing or predict in advance how many headers there can be. The cost is a Vec allocation, and predicting capacity is possible (pass Some(capacity) rather than None to DynRequest::new.

Future improvements

Create a macro parse_request! to automatically run parse, and then get_request. The lifetime restrictions make it hard to write a function to call them both, but this is not an issue for a macro.

Limitations

This have to be built with std, as Vec involved. We can instead use core, but still it is not going to compile with Rust 1.10.

As this is just a proof-of-concept, we can improve it later.