Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow iteration over headers, and enable multiple headers of a name #19

Open
nicholastmosher opened this issue May 29, 2022 · 3 comments

Comments

@nicholastmosher
Copy link

Hi there. I'm trying to convert to and from the http crate Request and Response types while actually sending the request through an embedded_svc::http::client::Client instance. I noticed while trying to rebuild the response that embedded_svc::http::Headers trait's API does not provide an iterator over header/value pairs, but rather provides a "key lookup" style API, e.g. let header = response.header("header name"). I have a few questions about this:

  • According to the http spec, it is possible for a request or response to have multiple headers with the same name (https://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.4.2.p.4). However, having a "lookup" style API like this one seems to imply that each header name will only have one value. Would it be feasible to define (perhaps in a new trait) an iterator-style API that is capable of yielding multiple entries for the same header name?
  • In current known implementations of the Headers trait, does it simply return a comma-separated string to indicate multiple values for the given header? Or are multiple values by the same header name silently dropped?
  • With the current Headers trait, is there any way to enumerate all of the names of headers in a response? It seems not.

I think that the http crate does a really good job at capturing the nuances of the http protocol, so it'd be nice if the http traits here were expressive enough to allow for a full round-trip conversion without loss of information (for suitable body types).

@MabezDev
Copy link
Member

In current known implementations of the Headers trait, does it simply return a comma-separated string to indicate multiple values for the given header? Or are multiple values by the same header name silently dropped?

Judging by this code the last parsed header with the same name will be present in the headers (silently dropping others).

With the current Headers trait, is there any way to enumerate all of the names of headers in a response? It seems not.

Currently, I don't believe so, I think you'd have to have a dependency on the implementation of the svc traits. Currently, in esp-idf-svc, headers are stored in a BTree.

I think that the http crate does a really good job at capturing the nuances of the http protocol, so it'd be nice if the http traits here were expressive enough to allow for a full round-trip conversion without loss of information (for suitable body types).

I agree! I've used it before, it's very nice! A PR would be most welcome :)

@ivmarkov
Copy link
Collaborator

ivmarkov commented Jun 1, 2022

I suggest let's wait here a week or so. I'm in the midst of doing some refactoring on the traits here so that all of those + the majority of the stuff in the utils module no longer needs types from the alloc crate.

One of the affected traits is the Headers trait, because of all the Cow tricks, which are now replaced with a simple &str refs.

The reason for all that is that ideally, we would like to support "Embassy-style" "all-static" "no-heap" "single-stack" async type of apps on ESP32 bare metal (ESP-IDF would always be the alloc STD-compatible thing though), as the former means much more runtime predictability (as in no stack overflows and allocation failures) which in turns results in more resilient firmware and makes a really good story for bare-metal Rust.

As for inspiring ourselves from the http crate - sure we can try that where it makes sense.
I'm not overly optimistic though because (a) this crate works with concrete structures, while we are limited to traits, which means higher complexity, lots of generics and lifetimes sprinkled everywhere and (b) the http crate uses alloc types, while - for the above reasons - we'll stay away from that.

@nicholastmosher
Copy link
Author

nicholastmosher commented Jun 1, 2022

Sounds good. And just to clarify, I'm not expecting to get full parity with http, but just hoping to fix some rough edges, such as wanting to enumerate the headers in a request or response. I'm all for keeping things generic in a no_std-friendly way 👍
Edit: I guess I did say "full round-trip conversion" but it makes sense that it may not be feasible to do that. But definitely I'd love to see more similar expressiveness where possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants