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.
abstract class HTTP::FileSystem
abstract def open(path : String) : IO
class HTTP::Dir < HTTP::FileSystem
def open(path : String) : IO
Then HTTP::StaticFileHandler could work like this
def initialize(@fs : HTTP::FileSystem, fallthrough = true, directory_listing = true)
@fallthrough = !!fallthrough
@directory_listing = !!directory_listing
# use @fs.open to open files
This could be implemented in a backwards compatible way by overloading
new(String) to create an
HTTP::Dir and use it.
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
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.
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.
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