hyperium / http

Rust HTTP types
Apache License 2.0
1.16k stars 291 forks source link

What is the performant and concise way to remove values from a HeaderMap containing duplicate HeaderName's? #431

Closed frenchtoastbeer closed 3 years ago

frenchtoastbeer commented 4 years ago

The http::header::HeaderMap struct doesn't seem to have a method to remove a single header's kv pair when duplicates are involved. When there isn't a duplicated header, I can call .insert(HeaderName, HeaderValue) and .remove(HeaderName) and the handling is what I would expect.

I want my code to be able to handle the situation where there are duplicated headers though, and there doesn't seem to be a .remove_kv("name", "value") for just one of the duplicate headers, leaving the others intact.

My solution so far has been to call the .entry(HeaderName), enumerate all the HeaderValues with a e.iter_mut().map(|value| value.clone()).collect::<Vec<_>>() (which is an eyesore) search the resulting vector for my value, .swap_remove(location) call .remove(HeaderName) (dropping all associated values), and then rebuild the duplicated headers by walking the vector of values that I cloned, making sure to first call .insert() and then subsequently call .append().

Please help!

Icelk commented 3 years ago

Isn't there a method on Entry::Occupied called remove_entry_mult which removes all? Then just HeaderMap.insert() :)

frenchtoastbeer commented 3 years ago

I'm not sure I follow, is the method you propose to 1. copy all duplicates, 2. remove them, and then 3. add back in the duplicates to preserve? That still seems like more work than necessary, though its probably a little better than what I was doing?

frenchtoastbeer commented 3 years ago

Nevermind, I see what you mean, the remove_entry_mult removes (and returns) all the values. This still feels overly complicated but the route you propose avoids cloning and so I believe it would at least be more performant, thanks for the suggestion!

Icelk commented 3 years ago

Glad I could help. Have a good day!