hyperium / http

Rust HTTP types
Apache License 2.0
1.15k stars 285 forks source link

Get fragment of Uri #127

Open J-F-Liu opened 7 years ago

J-F-Liu commented 7 years ago

Missing a uri.fragment() method?

seanmonstar commented 7 years ago

It was purposefully left out for now, since the server shouldn't receive or interact with the fragment, and the client should not send one. Do you have a specific need of it?

J-F-Liu commented 7 years ago

Just curiosity.

  1. http can be used in both server and client software.
  2. Some frameworks support both server side and client side rendering, client side has two modes: browserHistory and hashHistory, fragment maybe useful at first-time-rendering on server.
theduke commented 6 years ago

To me the URI type would be useful on it's own since there isn't any equivalent currently in the ecosystem. (That's why I'm also asking about extracting it into it's own crate).

I already have a situation where I need a URI and work with fragments.

Regardless, as @J-F-Liu said, http clients might want to work with the fragment.

briansmith commented 6 years ago

In https://github.com/runconduit/conduit/ we need to parse a URL and verify that it doesn't have a fragment.

Is the current behavior of Uri parsing to reject inputs without a fragment or to accept inputs without a fragment? Accepting inputs with a fragment and then not having any indication that there was a fragment part would be the only unacceptable behavior. Rejecting inputs with a fragment now but then accepting them later when the accessor is available would be a breaking change.

For these reasons, I think this should be resolved sooner than later.

carllerche commented 6 years ago

@briansmith for the record, could you explain why accepting inputs w/o a fragment is unacceptable behavior?

I believe that, in the context of HTTP, URIs are not supposed to have fragments. So, while the fragment is parsed and handled internally, there is not currently an accessor.

Personally, I don't have a problem adding one. It originally was not added in hopes that a case would come that helped better illustrate the need.

Rejecting a URI w/ a fragment is not possible as there are definitely misbehaving implementations out there.

briansmith commented 6 years ago

If a fragment is accepted (not rejected outright) then there needs to be, at least, a way to find out if a fragment was accepted. That way the application can decide how strict to be with those misbehaving applications on its own.

Anyway, currently in the Conduit project we're using http::Uri to parse the URLs in the configuration settings. Those settings aren't supposed to accept fragments (or paths) since the URL scheme (tcp://) doesn't even support fragments; in the future we'll probably use https:// URIs in those settings but even still we want to reject fragments because fragments don't make sense in that context.

seanmonstar commented 6 years ago

Does it make sense to have parsed a URI up to the fragment, but not include it at all? So, parsing "/foo#bar".parse() could return a Uri that has the bytes /foo?

Or is that surprising? We could also error if a fragment is found, but that makes it more annoying to parse things received on the internet, or user values, and it's true that a fragment is actually invalid.

Really, we just want to prevent the user from accidentally accepting fragments and then knowing they need to be stripped in most places. I feel a user should just not have to worry about them, because we killed them for you.

(I'd like to do the same with the userinfo part of authorities... Maybe we could have a relaxed parse method, and an into_strict method, if supporting this stuff were really needed.)

carllerche commented 6 years ago

Relaxed vs. strict might be the way to do this.

jongiddy commented 6 years ago

Microsoft Graph's OAuth2 implementation provides a real-world example where a server handling a fragment is required: https://github.com/hyperium/hyper/issues/1621

tekul commented 4 years ago

One use for accessing the fragment (or lack of it) is in validating the redirect_uri query parameter which an OAuth2/OpenID connect client passes to the authorization endpoint (or registers with the OP). The specification explicitly says that fragments are forbidden in this case https://tools.ietf.org/html/rfc6749#section-3.1.2.

m9xiuz commented 4 years ago

It was purposefully left out for now, since the server shouldn't receive or interact with the fragment, and the client should not send one. Do you have a specific need of it?

I needed it for URL redirection: https://docs.rs/warp/0.2.5/warp/redirect/fn.redirect.html I need to redirect a user to a specific location on the page. Please read this https://stackoverflow.com/questions/2286402/url-fragment-and-302-redirects/2305927#2305927

Icelk commented 3 years ago

Any new updates on this?

I think adding a method on Uri to get the fragment would be helpful, and maybe docs regarding some aspects of this issue?

I'd be happy to help out.

acfoltzer commented 2 years ago

This has come up as a need for us as well in order to support requests from non-browser clients that can send fragments to servers. (cc @katef)

craftytrickster commented 2 years ago

As mentioned by people like @acfoltzer , I also need to use this crate in a "client/browser like" application, and I need access to the fragment to perform an auth workflow.

I understand the emphasis on correctness here, and not wanting to allow access to the fragment under normal circumstances, but wouldn't this be the perfect use case for a cargo feature, such as "fragment-access-for-client-auth" or something?

gahag-cw commented 1 year ago

+1 OpenId requires servers to handle data in fragments instead of query params.

jrandolf commented 7 months ago

@seanmonstar Considering how ubiquitous http::Uri is, could we prioritize this feature? This prevents servers from implementing standardized protocols such as OpenID. In particular, http::Uri is often used as a standardized type for RFC 3986 URIs. It would make sense for http::Uri to actually conform to the spec.

gabibbo97 commented 7 months ago

Just to add, I have been running into this while validating data to conform with the OAuth 2.1 draft specification (https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-10.html). In order to check for conditions such as "The redirect URI MUST NOT include a fragment component." My current solution is a new struct which impl's Into and From