Skip to content

Commit

Permalink
Add a resourcePrefix for Middleware.serveResources
Browse files Browse the repository at this point in the history
As it is, `Middleware.serveResources(path)` going to serve any file at all under src/main/resources, including e.g. somebody's reference.conf file.
I added a resourcePrefix parameter for this, so that the resources served can be limited to, e.g.,  src/main/resources/public.

I also added delegates for serveResources and serveDirectory in Routes, as per this suggestion:

zio#2450 (comment)
  • Loading branch information
sullivan- committed Jun 6, 2024
1 parent d4168a7 commit 8342304
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
14 changes: 10 additions & 4 deletions zio-http/shared/src/main/scala/zio/http/Middleware.scala
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,8 @@ object Middleware extends HandlerAspects {
}
}

def fromResource(implicit trace: Trace): StaticServe[Any, Throwable] = make { (path, _) =>
Handler.fromResource(path.dropLeadingSlash.encode)
def fromResource(resourcePrefix: String)(implicit trace: Trace): StaticServe[Any, Throwable] = make { (path, _) =>
Handler.fromResource(s"${resourcePrefix}/${path.dropLeadingSlash.encode}")
}

}
Expand Down Expand Up @@ -398,9 +398,15 @@ object Middleware extends HandlerAspects {
* With this middleware in place, a request to
* `https://www.domain.com/assets/folder/file1.jpg` would serve the file
* `src/main/resources/folder/file1.jpg`.
*
* Provide a `resourcePrefix` if you want to limit the the resource files
* served. For instance, with `Middleware.serveResources(Path.empty /
* "assets", "public")`, a request to
* `https://www.domain.com/assets/folder/file1.jpg` would serve the file
* `src/main/resources/public/folder/file1.jpg`.
*/
def serveResources(path: Path)(implicit trace: Trace): Middleware[Any] =
toMiddleware(path, StaticServe.fromResource)
def serveResources(path: Path, resourcePrefix: String = ".")(implicit trace: Trace): Middleware[Any] =
toMiddleware(path, StaticServe.fromResource(resourcePrefix))

/**
* Creates a middleware for managing the flash scope.
Expand Down
33 changes: 33 additions & 0 deletions zio-http/shared/src/main/scala/zio/http/Routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package zio.http

import java.io.File

import zio._

import zio.http.Routes.ApplyContextAspect
Expand Down Expand Up @@ -293,6 +295,37 @@ object Routes extends RoutesCompanionVersionSpecific {
def singleton[Env, Err](h: Handler[Env, Err, (Path, Request), Response])(implicit trace: Trace): Routes[Env, Err] =
Routes(Route.route(RoutePattern.any)(h))

/**
* Creates routes for serving static files from the directory `docRoot` at the
* url path `path`.
*
* Example: `Routes.serveDirectory(Path.empty / "assets", new
* File("/some/local/path"))`
*
* With this routes in place, a request to
* `https://www.domain.com/assets/folder/file1.jpg` would serve the local file
* `/some/local/path/folder/file1.jpg`.
*/
def serveDirectory(path: Path, docRoot: File)(implicit trace: Trace): Routes[Any, Nothing] =
empty @@ Middleware.serveDirectory(path, docRoot)

/**
* Creates routes for serving static files from resources at the path `path`.
*
* Example: `Routes.serveResources(Path.empty / "assets")`
*
* With this routes in place, a request to
* `https://www.domain.com/assets/folder/file1.jpg` would serve the file
* `src/main/resources/folder/file1.jpg`.
*
* Provide a `resourcePrefix` if you want to limit the the resource files
* served. For instance, with `Routes.serveResources(Path.empty / "assets",
* "public")`, a request to `https://www.domain.com/assets/folder/file1.jpg`
* would serve the file `src/main/resources/public/folder/file1.jpg`.
*/
def serveResources(path: Path, resourcePrefix: String = ".")(implicit trace: Trace): Routes[Any, Nothing] =
empty @@ Middleware.serveResources(path, resourcePrefix)

private[http] final case class Tree[-Env](tree: RoutePattern.Tree[RequestHandler[Env, Response]]) { self =>
final def ++[Env1 <: Env](that: Tree[Env1]): Tree[Env1] =
Tree(self.tree ++ that.tree)
Expand Down

0 comments on commit 8342304

Please sign in to comment.