mirror of
https://github.com/datarhei/core.git
synced 2025-09-26 20:11:29 +08:00

Commits (Ingo Oppermann): - Add experimental SRT connection stats and logs - Hide /config/reload endpoint in reade-only mode - Add SRT server - Create v16 in go.mod - Fix data races, tests, lint, and update dependencies - Add trailing slash for routed directories (datarhei/restreamer#340) - Allow relative URLs in content in static routes Co-Authored-By: Ingo Oppermann <57445+ioppermann@users.noreply.github.com>
89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"path/filepath"
|
|
|
|
"github.com/datarhei/core/v16/http/api"
|
|
"github.com/datarhei/core/v16/http/cache"
|
|
"github.com/datarhei/core/v16/http/handler/util"
|
|
"github.com/datarhei/core/v16/io/fs"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// The DiskFSHandler type provides handlers for manipulating a filesystem
|
|
type DiskFSHandler struct {
|
|
cache cache.Cacher
|
|
filesystem fs.Filesystem
|
|
}
|
|
|
|
// NewDiskFS return a new DiskFS type. You have to provide a filesystem to act on and optionally
|
|
// a Cacher where files will be purged from if the Cacher is related to the filesystem.
|
|
func NewDiskFS(fs fs.Filesystem, cache cache.Cacher) *DiskFSHandler {
|
|
return &DiskFSHandler{
|
|
cache: cache,
|
|
filesystem: fs,
|
|
}
|
|
}
|
|
|
|
// GetFile returns the file at the given path
|
|
// @Summary Fetch a file from the filesystem
|
|
// @Description Fetch a file from the filesystem. If the file is a directory, a index.html is returned, if it exists.
|
|
// @ID diskfs-get-file
|
|
// @Produce application/data
|
|
// @Produce json
|
|
// @Param path path string true "Path to file"
|
|
// @Success 200 {file} byte
|
|
// @Success 301 {string} string
|
|
// @Failure 404 {object} api.Error
|
|
// @Router /{path} [get]
|
|
func (h *DiskFSHandler) GetFile(c echo.Context) error {
|
|
path := util.PathWildcardParam(c)
|
|
|
|
mimeType := c.Response().Header().Get(echo.HeaderContentType)
|
|
c.Response().Header().Del(echo.HeaderContentType)
|
|
|
|
file := h.filesystem.Open(path)
|
|
if file == nil {
|
|
return api.Err(http.StatusNotFound, "File not found", path)
|
|
}
|
|
|
|
stat, _ := file.Stat()
|
|
|
|
if stat.IsDir() {
|
|
path = filepath.Join(path, "index.html")
|
|
|
|
file.Close()
|
|
|
|
file = h.filesystem.Open(path)
|
|
if file == nil {
|
|
return api.Err(http.StatusNotFound, "File not found", path)
|
|
}
|
|
|
|
stat, _ = file.Stat()
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
c.Response().Header().Set("Last-Modified", stat.ModTime().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
|
|
|
|
if path, ok := stat.IsLink(); ok {
|
|
path = filepath.Clean("/" + path)
|
|
|
|
if path[0] == '/' {
|
|
path = path[1:]
|
|
}
|
|
|
|
return c.Redirect(http.StatusMovedPermanently, path)
|
|
}
|
|
|
|
c.Response().Header().Set(echo.HeaderContentType, mimeType)
|
|
|
|
if c.Request().Method == "HEAD" {
|
|
return c.Blob(http.StatusOK, "application/data", nil)
|
|
}
|
|
|
|
return c.Stream(http.StatusOK, "application/data", file)
|
|
}
|