feat(api): add server-side caching for requests that could benefit (#3463)
* feat(api): add server-side caching for requests that could benefit for them * fix(tests): do not cache responses while in tests * fix: remove commented out leftover code * chore(deps): update dependency html-webpack-plugin to v5.5.4 * Bundle embedded web app * fix: remove caching for web app assets under test * chore(tests): re-enable temporarily disabled test * chore(deps): update dependency typescript to v5.3.3 * Bundle embedded web app * chore(deps): update dependency npm to v10.2.5 * Bundle embedded web app --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Owncast <owncast@owncast.online>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/owncast/owncast/config"
|
||||
"github.com/owncast/owncast/core"
|
||||
@@ -13,8 +14,19 @@ import (
|
||||
"github.com/owncast/owncast/models"
|
||||
"github.com/owncast/owncast/router/middleware"
|
||||
"github.com/owncast/owncast/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
cache "github.com/victorspringer/http-cache"
|
||||
"github.com/victorspringer/http-cache/adapter/memory"
|
||||
)
|
||||
|
||||
type FileServerHandler struct {
|
||||
HLSPath string
|
||||
}
|
||||
|
||||
func (fsh *FileServerHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(rw, r, fsh.HLSPath)
|
||||
}
|
||||
|
||||
// HandleHLSRequest will manage all requests to HLS content.
|
||||
func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||
// Sanity check to limit requests to HLS file types.
|
||||
@@ -23,6 +35,26 @@ func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
responseCache, err := memory.NewAdapter(
|
||||
memory.AdapterWithAlgorithm(memory.LRU),
|
||||
memory.AdapterWithCapacity(20),
|
||||
memory.AdapterWithStorageCapacity(209_715_200),
|
||||
)
|
||||
if err != nil {
|
||||
log.Warn("unable to create web cache", err)
|
||||
}
|
||||
|
||||
// Since HLS segments cannot be changed once they're rendered, we can cache
|
||||
// individual segments for a long time.
|
||||
longTermHLSSegmentCache, err := cache.NewClient(
|
||||
cache.ClientWithAdapter(responseCache),
|
||||
cache.ClientWithTTL(30*time.Second),
|
||||
cache.ClientWithExpiresHeader(),
|
||||
)
|
||||
if err != nil {
|
||||
log.Warn("unable to create web cache client", err)
|
||||
}
|
||||
|
||||
requestedPath := r.URL.Path
|
||||
relativePath := strings.Replace(requestedPath, "/hls/", "", 1)
|
||||
fullPath := filepath.Join(config.HLSStoragePath, relativePath)
|
||||
@@ -48,6 +80,10 @@ func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
cacheTime := utils.GetCacheDurationSecondsForPath(relativePath)
|
||||
w.Header().Set("Cache-Control", "public, max-age="+strconv.Itoa(cacheTime))
|
||||
|
||||
fileServer := &FileServerHandler{HLSPath: fullPath}
|
||||
longTermHLSSegmentCache.Middleware(fileServer).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
middleware.EnableCors(w)
|
||||
|
||||
Reference in New Issue
Block a user