akka / akka-http

The Streaming-first HTTP server/module of Akka
https://doc.akka.io/docs/akka-http
Other
1.34k stars 595 forks source link

Support Relative URLs not anchored at the root #4245

Open bblfish opened 1 year ago

bblfish commented 1 year ago

In RFC5988 and it's successor RFC8288: Web Linking the BNF of the Link header is defined as

link-value = "<" URI-Reference ">" *( OWS ";" OWS link-param )

where URI-Reference can be a relative url as defined in rfc3986.

I am using the actor hierarchy to map a collection hierarchy so that I should for example be able to compare to actor URIs and build up a relative path such as <../../.acl> without needing to know what the full url of the server is, nor what the root url is. That is userful as the server need not serve urls from the root.

The problem with the current Link header is that it takes a sequences of akka.http.scaladsl.model.headers.LinkValue objects, where case class LinkValue(uri: Uri, params: immutable.Seq[LinkParam]) is constructed using Uri which does not support urls containing ../ path segments.

bblfish commented 1 year ago

A workaround is to use RawHeader in this case.

RawHeader("Link","<../.acl>; rel=\"https://www.w3.org/ns/auth/acl#accessControl\"")

But given the close mapping between URLs and akka paths really a future version should perhaps take relative urls more seriously.

But that makes me wonder what happens if an Akka http client parses such a Link header... It should relativise the URLs to the base, but akka Uri does not have a method to do that.

johanandren commented 1 year ago

I think this is the first time we have seen any requests to support such root-relative link headers (the only thing related I can find is a previous issue by you https://github.com/akka/akka-http/issues/99 ). Not anything we will prioritize but we'd be open to looking at PRs allowing such. Gut feeling is that it seems tricky to do in a binary compatible way.

bblfish commented 1 year ago

Speaking of the Link relation it seems to me that there it is a bit wasteful in cpu to calculate if the LinkValue relation contains the characters " ,;" before quoting one could always quote, especially when given a Uri. I think a better model for LinkParam in Scala3 would be LinkParam(key: String|Ur)I, then for Uri one could automatically add the quotes.

This has led me to discover a bug in http4s which assumed the quoting.