http
http copied to clipboard
Allow empty authority in absolute URIs
Fixes #323
This removes the restriction preventing empty authority in URIs. The canonical example of this is file:/// which has a zero-length authority. While these may not be relevant for a web server, there are many domains that need these sorts of alternative URIs (for example Webview-based software which reads local resources).
https://datatracker.ietf.org/doc/html/rfc3986 pretty clearly describes the authority as optional in all situations AFAICT, but it mentions that schema-specific restrictions may be in place.
This is the case for HTTP addresses, described in https://www.rfc-editor.org/rfc/rfc9110.html#name-identifiers-in-http
The origin server for an "https" URI is identified by the authority component ... A sender MUST NOT generate an "https" URI with an empty host identifier. A recipient that processes such a URI reference MUST reject it as invalid.
It's possible that some users of this library in a strictly-http context may be relying on this checking the validity of the HTTP identifier for them. I'm not sure how to handle this, maybe with a version bump? The legacy behavior could be considered a bug though.
Eventually a separate HttpUri type or something that performs the additional checks when constructed might be useful.
I'm not immediately against this change, but I am a bit skeptical. Notably, this crate is purposefully meant for the HTTP usecase, not a general URL parser. (HttpUri seems like it already exists, http::Uri).
Also, recently opened: #696.
FWIW I opened this because I thought @carllerche had given the okay for it in #323 , but you're right, this is http::Uri after all.
Despite varied requirements, the rust ecosystem still hasn't seen a second Uri crate and this is used pretty widely - I'm not sure the ecosystem could support another implementation of a Uri crate. Is there a way some of the core functionality could be shared with another crate with a more permissive frontend in such a way that the types would be trivially convertible?
On the other hand, I don't think any software relies on this check for correct operation... I think this error is at most used to detect user mistakes early. And in that case, I think other code that consumes Uri probably already performs such a check - for instance, "".to_socket_addrs().unwrap() returns Error { kind: InvalidInput, message: "invalid socket address" } which conveys more or less the same information. From a user perspective you'd troubleshoot "" the same way you'd troubleshoot any other incorrect host name.
Could this be merged?
I think there'd be less misuse of this type if it was called http::RequestTarget which is more descriptive of it's actual purpose (using the specs' BNF language, see ). In this context, file:/// is not valid.
I agree with the assessment that this crate is designed for specifically HTTP URI use cases, and for generic URL situations (client-side, webview, etc) something more like the url::Url type is approprirate since it models and accepts these situations.
Seems like we're stuck here between two crates:
http::Uriwhich is named based on URI, but some parts are tied to http like this one.url:Url, which doesn't allow custom schemes, because it's consider an URL, not URI.
Since the authority (and scheme, username, password...) is usually removed before being sent to a server inside HTTP, it can be necessary to create a URI appropriate for use there. Such as when the connection is to a device over link-layer v6, discovered via mDNS. One can not pass a name for the authority, because the socket needs to be properly crafted. (Yes, maybe can do fe80::1234%eth0, ... do we support draft-ietf-6man-zone-ui-10 ... , but going back and forth to strings seems silly, and maybe there is a hidden attack)