scalahttp4s

How to get the full URL from an Http4s Request


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


Solution

  • 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.