rtsp-rs icon indicating copy to clipboard operation
rtsp-rs copied to clipboard

why not use a mature URI crate?

Open ultrasaurus opened this issue 5 years ago • 6 comments

https://github.com/servo/rust-url seems to be actively worked on and hyper::uri also seems to be used in some networking code samples I've seen.

The sgodwincs/uriparse-rs README says "The goal of this crate is to provide types for efficiently creating, modifying, and parsing URIs, relative references, and URI references." Are the other libraries not efficient?

It seems like it would make the library more usable for URI interface to be something used by other popular Rust libraries (and create long-term efficiency).... unless there's a pretty big reason not to.

ultrasaurus avatar Jun 30 '19 14:06 ultrasaurus

The main reason is that the url crate is based on a different standard than the uriparse crate.

The url crate is based on https://url.spec.whatwg.org/ while the uriparse crate is based on RFC3986. I originally was using the url crate, but the standards aren't 100% compatible and the RTSP specification uses RFC3986, not the URL standard.

What specifically do you find inconvenient in URI interface? As far as I remember, the interfaces are fairly similar.

sgodwincs avatar Jun 30 '19 16:06 sgodwincs

For completeness, hyper::uri also isn't really a URI as defined by RFC3986 despite being named as such. It's really a request-target as defined in RFC7230, so unfortunately isn't 100% compatible here.

sgodwincs avatar Jun 30 '19 17:06 sgodwincs

I'm not sure that I understand why a request-target is not compatible with what is needed by RTSP. It seems that it adds an asterisk, which is also used by RTSP. Am I missing something?

ultrasaurus avatar Jul 01 '19 18:07 ultrasaurus

RTSP requests require specifying an absolute URI, whereas HTTP requests do not because they use the Host header instead.

E.g. GET / HTTP/1.11 is a valid info line for HTTP, but SETUP / RTSP/2.0 is not for RTSP, since the URI is not absolute. The only exception is what you mentioned *. The authors of the http crate even mention that using the name "uri" is misleading since / isn't a URI because it has no scheme. It's a relative reference which uriparse supports as a different type RelativeReference.

It should be be mentioned that the scopes of hyper::uri and uriparse are different. They both focus on avoiding allocations (whereas the url crate will always do an allocation on parsing to create a new serialization which has its own pros/cons), but hyper::uri is intentionally simplistic. It doesn't support normalization of components nor the RFC3986 URI + relative reference resolve algorithm. In general, I designed uriparse to be 1-to-1 compatible with RFC3986, while focusing on type correctness and performance.

sgodwincs avatar Jul 01 '19 19:07 sgodwincs

Curious about this, I created a little compare/contrast of three URI crates: https://github.com/ultrasaurus/rust-uri-comparison

It seems to me that uriparse has arbitrarily different syntax (most notably lacking parse support) with little clear added value. I hear you that servo/rust-url favors an approach that allocates more memory than is strictly needed, but as you say hyper::uri matches your philosophy -- it supports Absolute URIs and, if you wanted to, check for that requirement.

I'd be interested in understanding how you expect "correctness" to apply in practice, and if you ever attempted to contribute to hyper::uri to add what you felt was missing. (Of course, it's your library, you can do what you want, just curious about the choices here.)

ultrasaurus avatar Jul 10 '19 01:07 ultrasaurus

It seems to me that uriparse has arbitrarily different syntax (most notably lacking parse support) with little clear added value

Can you expand on what syntax you find to be very different and why you find it to perhaps be worse? As for not having parse support, I'm assuming you are referring to the parse function? The http and rust-url crates have been stable for some time, so they have been accustomed to using the FromStr trait which provides the parse function. uriparse was made initially with nightly (and still is due to the non_exhaustive feature) so it was able to take advantage of the not-yet stable TryFrom trait which provides a try_from function from an arbitrary type. The TryFrom trait is really just a generalization of the FromStr trait, but it's true it's not implemented for the uriparse's types. For completeness and consistency, it's absolutely fine with me to implement both, and it is trivial to do so.

...but as you say hyper::uri matches your philosophy -- it supports Absolute URIs and, if you wanted to, check for that requirement.

I'm mainly against using hyper::uri simply because it is intended to be used with HTTP and not as a compatible RFC3986 URI. This view has been reinforced by the http crate authors (which is where hyper::uri either comes from now or will in the future).

I'd be interested in understanding how you expect "correctness" to apply in practice, and if you ever attempted to contribute to hyper::uri to add what you felt was missing

My comment before was not intended to say that the hyper::uri implementation was "incorrect", I was just stating it has one of the goals of uriparse. Specifically, I am a very big fan of using the type system to ensure that if an instance of a type exists, it can be guaranteed to meet its constraints and be "correct". It's true that this does introduce code verbosity in some use cases, but it's a tradeoff I'm willing to make personally.

sgodwincs avatar Jul 10 '19 04:07 sgodwincs