<commit_before>
# Static Files

Http4s can serve static files, subject to a configuration policy. There are three
locations that Http4s can serve static content from: the filesystem, resources
using the classloader, and WebJars.

All of these solutions are most likely slower than the equivalent in nginx or a
similar static file hoster, but they're often fast enough.

## Getting Started

To use fileService, the only configuration required is the relative path to the directory to serve.
The service will automatically serve index.html if the request path is not a file. This service will also
remove dot segments, to prevent attackers from reading files not contained in the directory
being served.

```scala mdoc
import cats.effect._
import org.http4s.blaze.server.BlazeServerBuilder
import org.http4s.server.Server
import org.http4s.server.staticcontent._

object SimpleHttpServer extends IOApp {
  override def run(args: List[String]): IO[ExitCode] =
    app.use(_ => IO.never).as(ExitCode.Success)

  val app: Resource[IO, Server] =
    for {
      server <- BlazeServerBuilder[IO]
        .bindHttp(8080)
        .withHttpApp(fileService[IO](FileService.Config(".")).orNotFound)
        .resource<commit_msg>Update static docs to use ember<commit_after>
# Static Files

Http4s can serve static files, subject to a configuration policy. There are three
locations that Http4s can serve static content from: the filesystem, resources
using the classloader, and WebJars.

All of these solutions are most likely slower than the equivalent in nginx or a
similar static file hoster, but they're often fast enough.

## Getting Started

To use fileService, the only configuration required is the relative path to the directory to serve.
The service will automatically serve index.html if the request path is not a file. This service will also
remove dot segments, to prevent attackers from reading files not contained in the directory
being served.

```scala mdoc
import cats.effect._
import com.comcast.ip4s._
import org.http4s.ember.server.EmberServerBuilder
import org.http4s.server.Server
import org.http4s.server.staticcontent._

object SimpleHttpServer extends IOApp {
  override def run(args: List[String]): IO[ExitCode] =
    app.use(_ => IO.never).as(ExitCode.Success)

  val app: Resource[IO, Server] =
    for {
      server <- EmberServerBuilder
        .default[IO]
        .withHost(ipv4"0.0.0.0")
        .withPort(port"8080")
        .withHttpApp(fileService[IO](FileService.Config(".")).orNotFound)
        .build
{'fraction_non_alphanumeric': 0.07275603005140371, 'fraction_numerical': 0.009489916963226572, 'mean_word_length': 4.205761316872428, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2946813', 'n_tokens_mistral': 709, 'n_tokens_neox': 678, 'n_words': 286}