diff --git a/internal/resource/delivery/http/resource_http.go b/internal/resource/delivery/http/resource_http.go new file mode 100644 index 0000000..42faba3 --- /dev/null +++ b/internal/resource/delivery/http/resource_http.go @@ -0,0 +1,48 @@ +package http + +import ( + "bytes" + "context" + "fmt" + "io" + "io/fs" + "net/http" + + "source.toby3d.me/toby3d/home/internal/domain" + "source.toby3d.me/toby3d/home/internal/resource" +) + +type Handler struct { + contentDir fs.FS + resources resource.UseCase +} + +func NewHandler(resources resource.UseCase, contentDir fs.FS) *Handler { + return &Handler{ + contentDir: contentDir, + resources: resources, + } +} + +func (h *Handler) Handle(ctx context.Context, path string) (http.Handler, error) { + res, err := h.resources.Do(ctx, path) + if err != nil { + return nil, err + } + + file, err := h.contentDir.Open(res.File.Filename()) + if err != nil { + return nil, fmt.Errorf("cannot open resource: %w", err) + } + defer file.Close() + + resBytes, err := io.ReadAll(file) + if err != nil { + return nil, fmt.Errorf("cannot read resource: %w", err) + } + + // TODO(toby3d): ugly workaround, refactor that. + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.ServeContent(w, r, res.Name(), domain.ResourceModTime(res), bytes.NewReader(resBytes)) + }), nil +}