# Introduce HTTP::Dir and HTTP::FileSystem

**URL:** <https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014>\
**Category:** Crystal Contrib\
**Created:** [July 31, 2019, 8:54am UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014 "2019-07-31T08:54:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![UlisseMini](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/ulissemini/32/509_2.png) [@UlisseMini](https://forum.crystal-lang.org/u/UlisseMini)\
**Post date:** [July 31, 2019, 8:54am UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014/1 "2019-07-31T08:54:27Z")

</div>

`HTTP::StaticFileHandler` should use an abstraction instead of a string to serve files from.

In go we have `http.Dir` that is a wrapper around a `string` but it adds the `Open(name string) (File, error)` method, i think something similar would be great to have in crystal, here’s my attempt at translating the same abstraction we have in go.

```auto
# https://godoc.org/net/http#FileSystem
abstract class HTTP::FileSystem
  abstract def open(path : String) : IO
  end
end

# https://godoc.org/net/http#Dir
class HTTP::Dir < HTTP::FileSystem
  def open(path : String) : IO
    # ...
  end
end

```

Then HTTP::StaticFileHandler could work like this

```auto
class HTTP::StaticFileHandler
    def initialize(@fs : HTTP::FileSystem, fallthrough = true, directory_listing = true)
    @fallthrough = !!fallthrough
    @directory_listing = !!directory_listing
  end

  # use @fs.open to open files
end

```

This could be implemented in a backwards compatible way by overloading `new(String)` to create an `HTTP::Dir` and use it.

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [July 31, 2019, 9:25am UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014/2 "2019-07-31T09:25:15Z")

</div>

I don’t think it makes much sense to introduce two new types just for `StaticFileHandler`. To customize the way this handler accesses a file system, it would be much cleaner to just extract all filesystem-specific calls to private methods which can be overridden in a subclass.

As mentioned earlier, in the long term it might be great to have some kind of filesystem abstraction, but it should be universal, not just for `StaticFileHandler`.

---

<div class="post-metadata">

**Author:** ![UlisseMini](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/ulissemini/32/509_2.png) [@UlisseMini](https://forum.crystal-lang.org/u/UlisseMini)\
**Post date:** [July 31, 2019, 4:05pm UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014/3 "2019-07-31T16:05:09Z")

</div>

I agree, having a global FIleSystem abstraction would be nicer in the long term, I’m going to refactor the filesystem calls in `HTTP::StaticFileHandler` into private methods and PR it, if thats alright with you?

EDIT: After implementing it its pretty hackish, i think implementing the filesystem abstraction should be opened as an issue on the crystal repo, I’ll open it if you agree.

---

<div class="post-metadata">

**Author:** ![Sirikon](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/sirikon/32/917_2.png) [@Sirikon](https://forum.crystal-lang.org/u/Sirikon)\
**Post date:** [July 24, 2020, 11:10am UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014/4 "2020-07-24T11:10:05Z")

</div>

Has this Issue been created already? I’m interested.

Coming from Golang, the global `FileSystem` abstraction is a huge enabler for a lot of cool stuff.

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [July 24, 2020, 12:42pm UTC](https://forum.crystal-lang.org/t/introduce-http-dir-and-http-filesystem/1014/5 "2020-07-24T12:42:24Z")

</div>

I’m on board on refactoring the StaticFileHandler to isolate syscalls and other logic into _protected_ methods. That will allow to subclass and customize the behaviour in some scenarios.

Yet I would consider those as `:nodoc:` or not stable api. It won’t be worst as the current state were some frameworks monkey patch StaticFileHandler to extend the behavior to:

- handle partial responses
- remove some url components to mount the handler at other than root. (This should be handled in a more generic / composable `RouteHandler` at some point though)
- customize the content to list in a directory
- customize the directory listing template
