I'm trying to obtain the beginning of the URL that a client used to access a webserver in Http4s. I.e. given a Request[F]
I want to obtain the string "http://localhost:8080"
or "https://my-app.company.com"
depending on where the server is deployed.
In a server implementation with Http4s, when receiving a Request via something like
HttpRoutes.of[IO] {
case req =>
println(req.uri)
???
}
I only ever seem to get a relative URI, e.g. /
or /foo/bar
- the scheme
and authority
fields on the Uri
are both None
.
It looks like I can pull the localhost:8080
part from the Host
header on the request, but I have no solution for the scheme (http://
or https://
).
How can I fill in the correct value for request.uri.scheme
? And is there a more appropriate way to obtain the host
?
FWIW I'm using http4s 0.22
CodePudding user response:
You can't get it while using Blaze as an HTTP server. There are workarounds. You can catch bound of a server:
By port:
[io-compute-4] INFO org.http4s.blaze.channel.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:8080
By schema:
[io-compute-4] INFO org.http4s.blaze.server.BlazeServerBuilder - http4s v1.0.0-M33 on blaze v1.0.0-M33 started at http://[::]:8080/
Or you can map 8080 to HTTP and 8081 to HTTPS and make pattern matching on it.
A bad workaround would be to add it as an HTTP header and read it via Headers It legacy practice but many legacy software companies are still using this approach.