In Http4s 0.16.6a, I had the following service.
import org.http4s.server.staticcontent._
import org.http4s._
object StaticFiles {
val basepath = ...
def apply(): HttpService = Service.lift(request => {
val file = basepath + request.uri.path
StaticFile.fromString(file, Some(request)).fold {
Pass.now // aka fallthrough
} {
NoopCacheStrategy.cache(request.pathInfo, _)
}
})
}
It takes the path from the url and tries to work out if a static file can be served. So a GET request to /index.html
would try and load it with fromFile
and if it can't be found, fallthrough or "Pass". When composed with other services using ||
, it meant the total function (from lift
) would be treated a bit like a partial function (from apply
).
I can't seem to convert this over to Http4s 0.18.x.
The Http4s docs suggest the following:
import cats.effect._
import org.http4s._
import org.http4s.dsl.io._
import java.io.File
val service = HttpService[IO] {
case request @ GET -> Root / "index.html" =>
StaticFile.fromFile(new File("relative/path/to/index.html"), Some(request))
.getOrElseF(NotFound()) // In case the file doesn't exist
}
Which is the basic form of what I'm trying to do, only I'd like to generify it a little and not create a partial function for every file I want to serve. i.e. avoid this:
case request @ GET -> Root / "index.html" => ???
case request @ GET -> Root / "fileA.html" => ???
case request @ GET -> Root / "fileB.html" => ???
So, my questions are:
- Is there the concept of
Pass
and passthough when usinglift
in 0.18? - How to I use the
NooopCacheStretegy
withlift
? - Ultimately, how to I convert the code above to 0.18?
My endeavours so far have lead to this abomination (which obvs doesn't compile):
def apply(): HttpService[IO] = HttpService.lift(request => {
val target = basepath + request.uri.path
StaticFile.fromString[IO](target, Some(request)).fold {
// passthrough
IO.pure(???)
} {
// process request
response => NoopCacheStrategy[IO].cache(request.pathInfo, response).unsafeRunSync()
}
})
Note that I'm trying to use HttpService.lift
not OptionT.liftF
(as recommended). Mostly because I have no clue how to!