mirror of
https://github.com/owncast/owncast.git
synced 2024-11-24 05:38:58 +03:00
chore: reverting the current implementation of http response caching
This commit is contained in:
parent
df7eb5e38d
commit
bb7de347c5
8 changed files with 34 additions and 202 deletions
|
@ -30,8 +30,4 @@ var (
|
||||||
|
|
||||||
// PublicFilesPath is the optional directory for hosting public files.
|
// PublicFilesPath is the optional directory for hosting public files.
|
||||||
PublicFilesPath = filepath.Join(DataDirectory, "public")
|
PublicFilesPath = filepath.Join(DataDirectory, "public")
|
||||||
|
|
||||||
// DisableResponseCaching will disable caching of API and resource
|
|
||||||
// responses. Disable this feature to turn off the optimizations.
|
|
||||||
DisableResponseCaching = false
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/owncast/owncast/config"
|
"github.com/owncast/owncast/config"
|
||||||
"github.com/owncast/owncast/core"
|
"github.com/owncast/owncast/core"
|
||||||
|
@ -14,24 +13,8 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
cache "github.com/victorspringer/http-cache"
|
|
||||||
"github.com/victorspringer/http-cache/adapter/memory"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
hlsCacheAdapter *cache.Adapter
|
|
||||||
hlsResponseCache *cache.Client
|
|
||||||
)
|
|
||||||
|
|
||||||
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.
|
// HandleHLSRequest will manage all requests to HLS content.
|
||||||
func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
// Sanity check to limit requests to HLS file types.
|
// Sanity check to limit requests to HLS file types.
|
||||||
|
@ -40,32 +23,6 @@ func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if hlsCacheAdapter == nil {
|
|
||||||
ca, err := memory.NewAdapter(
|
|
||||||
memory.AdapterWithAlgorithm(memory.LRU),
|
|
||||||
memory.AdapterWithCapacity(50),
|
|
||||||
memory.AdapterWithStorageCapacity(104_857_600),
|
|
||||||
)
|
|
||||||
hlsCacheAdapter = &ca
|
|
||||||
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.
|
|
||||||
if hlsResponseCache == nil {
|
|
||||||
rc, err := cache.NewClient(
|
|
||||||
cache.ClientWithAdapter(*hlsCacheAdapter),
|
|
||||||
cache.ClientWithTTL(30*time.Second),
|
|
||||||
cache.ClientWithExpiresHeader(),
|
|
||||||
)
|
|
||||||
hlsResponseCache = rc
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache client", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestedPath := r.URL.Path
|
requestedPath := r.URL.Path
|
||||||
relativePath := strings.Replace(requestedPath, "/hls/", "", 1)
|
relativePath := strings.Replace(requestedPath, "/hls/", "", 1)
|
||||||
fullPath := filepath.Join(config.HLSStoragePath, relativePath)
|
fullPath := filepath.Join(config.HLSStoragePath, relativePath)
|
||||||
|
@ -91,10 +48,6 @@ func HandleHLSRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
} else {
|
} else {
|
||||||
cacheTime := utils.GetCacheDurationSecondsForPath(relativePath)
|
cacheTime := utils.GetCacheDurationSecondsForPath(relativePath)
|
||||||
w.Header().Set("Cache-Control", "public, max-age="+strconv.Itoa(cacheTime))
|
w.Header().Set("Cache-Control", "public, max-age="+strconv.Itoa(cacheTime))
|
||||||
|
|
||||||
fileServer := &FileServerHandler{HLSPath: fullPath}
|
|
||||||
hlsResponseCache.Middleware(fileServer).ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
middleware.EnableCors(w)
|
middleware.EnableCors(w)
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/owncast/owncast/config"
|
"github.com/owncast/owncast/config"
|
||||||
"github.com/owncast/owncast/core"
|
"github.com/owncast/owncast/core"
|
||||||
|
@ -17,45 +16,12 @@ import (
|
||||||
"github.com/owncast/owncast/static"
|
"github.com/owncast/owncast/static"
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
cache "github.com/victorspringer/http-cache"
|
|
||||||
"github.com/victorspringer/http-cache/adapter/memory"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
indexCacheAdapter *cache.Adapter
|
|
||||||
indexBotSearchCache *cache.Client
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IndexHandler handles the default index route.
|
// IndexHandler handles the default index route.
|
||||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
middleware.EnableCors(w)
|
middleware.EnableCors(w)
|
||||||
|
|
||||||
if indexCacheAdapter == nil {
|
|
||||||
ca, err := memory.NewAdapter(
|
|
||||||
memory.AdapterWithAlgorithm(memory.LFU),
|
|
||||||
memory.AdapterWithCapacity(50),
|
|
||||||
memory.AdapterWithStorageCapacity(104_857_600),
|
|
||||||
)
|
|
||||||
indexCacheAdapter = &ca
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if indexBotSearchCache == nil {
|
|
||||||
rc, err := cache.NewClient(
|
|
||||||
cache.ClientWithAdapter(*indexCacheAdapter),
|
|
||||||
cache.ClientWithTTL(30*time.Second),
|
|
||||||
cache.ClientWithExpiresHeader(),
|
|
||||||
cache.ClientWithRefreshKey("bot-search-page"),
|
|
||||||
cache.ClientWithExpiresHeader(),
|
|
||||||
)
|
|
||||||
indexBotSearchCache = rc
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache client", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isIndexRequest := r.URL.Path == "/" || filepath.Base(r.URL.Path) == "index.html" || filepath.Base(r.URL.Path) == ""
|
isIndexRequest := r.URL.Path == "/" || filepath.Base(r.URL.Path) == "index.html" || filepath.Base(r.URL.Path) == ""
|
||||||
|
|
||||||
if utils.IsUserAgentAPlayer(r.UserAgent()) && isIndexRequest {
|
if utils.IsUserAgentAPlayer(r.UserAgent()) && isIndexRequest {
|
||||||
|
@ -66,7 +32,7 @@ func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// For search engine bots and social scrapers return a special
|
// For search engine bots and social scrapers return a special
|
||||||
// server-rendered page.
|
// server-rendered page.
|
||||||
if utils.IsUserAgentABot(r.UserAgent()) && isIndexRequest {
|
if utils.IsUserAgentABot(r.UserAgent()) && isIndexRequest {
|
||||||
indexBotSearchCache.Middleware(http.HandlerFunc(handleScraperMetadataPage))
|
handleScraperMetadataPage(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -31,9 +31,9 @@ require (
|
||||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||||
golang.org/x/crypto v0.17.0 // indirect
|
golang.org/x/crypto v0.15.0 // indirect
|
||||||
golang.org/x/net v0.18.0
|
golang.org/x/net v0.18.0
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
golang.org/x/sys v0.14.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/prometheus/client_golang v1.17.0
|
require github.com/prometheus/client_golang v1.17.0
|
||||||
|
@ -75,7 +75,6 @@ require (
|
||||||
github.com/CAFxX/httpcompression v0.0.9
|
github.com/CAFxX/httpcompression v0.0.9
|
||||||
github.com/andybalholm/cascadia v1.3.2
|
github.com/andybalholm/cascadia v1.3.2
|
||||||
github.com/mssola/user_agent v0.6.0
|
github.com/mssola/user_agent v0.6.0
|
||||||
github.com/victorspringer/http-cache v0.0.0-20231006141456-6446fe59efba
|
|
||||||
github.com/yuin/goldmark-emoji v1.0.2
|
github.com/yuin/goldmark-emoji v1.0.2
|
||||||
gopkg.in/evanphx/json-patch.v5 v5.7.0
|
gopkg.in/evanphx/json-patch.v5 v5.7.0
|
||||||
mvdan.cc/xurls v1.1.0
|
mvdan.cc/xurls v1.1.0
|
||||||
|
|
14
go.sum
14
go.sum
|
@ -134,8 +134,6 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f
|
||||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
github.com/valyala/gozstd v1.20.1 h1:xPnnnvjmaDDitMFfDxmQ4vpx0+3CdTg2o3lALvXTU/g=
|
github.com/valyala/gozstd v1.20.1 h1:xPnnnvjmaDDitMFfDxmQ4vpx0+3CdTg2o3lALvXTU/g=
|
||||||
github.com/valyala/gozstd v1.20.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
|
github.com/valyala/gozstd v1.20.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
|
||||||
github.com/victorspringer/http-cache v0.0.0-20231006141456-6446fe59efba h1:+oqDKQIOdkkvro1psUKtI4oH9WBeKkGY2S8h9/lo288=
|
|
||||||
github.com/victorspringer/http-cache v0.0.0-20231006141456-6446fe59efba/go.mod h1:D1AD6nlXv7HkIfTVd8ZWK1KQEiXYNy/LbLkx8H9tIQw=
|
|
||||||
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
||||||
|
@ -149,8 +147,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||||
|
@ -184,15 +182,15 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
|
27
main.go
27
main.go
|
@ -17,18 +17,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dbFile = flag.String("database", "", "Path to the database file.")
|
dbFile = flag.String("database", "", "Path to the database file.")
|
||||||
logDirectory = flag.String("logdir", "", "Directory where logs will be written to")
|
logDirectory = flag.String("logdir", "", "Directory where logs will be written to")
|
||||||
backupDirectory = flag.String("backupdir", "", "Directory where backups will be written to")
|
backupDirectory = flag.String("backupdir", "", "Directory where backups will be written to")
|
||||||
enableDebugOptions = flag.Bool("enableDebugFeatures", false, "Enable additional debugging options.")
|
enableDebugOptions = flag.Bool("enableDebugFeatures", false, "Enable additional debugging options.")
|
||||||
enableVerboseLogging = flag.Bool("enableVerboseLogging", false, "Enable additional logging.")
|
enableVerboseLogging = flag.Bool("enableVerboseLogging", false, "Enable additional logging.")
|
||||||
restoreDatabaseFile = flag.String("restoreDatabase", "", "Restore an Owncast database backup")
|
restoreDatabaseFile = flag.String("restoreDatabase", "", "Restore an Owncast database backup")
|
||||||
newAdminPassword = flag.String("adminpassword", "", "Set your admin password")
|
newAdminPassword = flag.String("adminpassword", "", "Set your admin password")
|
||||||
newStreamKey = flag.String("streamkey", "", "Set a temporary stream key for this session")
|
newStreamKey = flag.String("streamkey", "", "Set a temporary stream key for this session")
|
||||||
webServerPortOverride = flag.String("webserverport", "", "Force the web server to listen on a specific port")
|
webServerPortOverride = flag.String("webserverport", "", "Force the web server to listen on a specific port")
|
||||||
webServerIPOverride = flag.String("webserverip", "", "Force web server to listen on this IP address")
|
webServerIPOverride = flag.String("webserverip", "", "Force web server to listen on this IP address")
|
||||||
rtmpPortOverride = flag.Int("rtmpport", 0, "Set listen port for the RTMP server")
|
rtmpPortOverride = flag.Int("rtmpport", 0, "Set listen port for the RTMP server")
|
||||||
disableResponseCaching = flag.Bool("disableResponseCaching", false, "Do not optimize performance by caching of web responses")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint:cyclop
|
// nolint:cyclop
|
||||||
|
@ -43,10 +42,6 @@ func main() {
|
||||||
config.BackupDirectory = *backupDirectory
|
config.BackupDirectory = *backupDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
if *disableResponseCaching {
|
|
||||||
config.DisableResponseCaching = *disableResponseCaching
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the data directory if needed
|
// Create the data directory if needed
|
||||||
if !utils.DoesFileExists("data") {
|
if !utils.DoesFileExists("data") {
|
||||||
if err := os.Mkdir("./data", 0o700); err != nil {
|
if err := os.Mkdir("./data", 0o700); err != nil {
|
||||||
|
|
101
router/router.go
101
router/router.go
|
@ -24,45 +24,10 @@ import (
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
"github.com/owncast/owncast/yp"
|
"github.com/owncast/owncast/yp"
|
||||||
|
|
||||||
cache "github.com/victorspringer/http-cache"
|
|
||||||
"github.com/victorspringer/http-cache/adapter/memory"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start starts the router for the http, ws, and rtmp.
|
// Start starts the router for the http, ws, and rtmp.
|
||||||
func Start() error {
|
func Start() error {
|
||||||
// Setup a web response cache
|
|
||||||
enableCache := !config.DisableResponseCaching
|
|
||||||
|
|
||||||
responseCache, err := memory.NewAdapter(
|
|
||||||
memory.AdapterWithAlgorithm(memory.LRU),
|
|
||||||
memory.AdapterWithCapacity(50),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
superShortCacheClient, err := cache.NewClient(
|
|
||||||
cache.ClientWithAdapter(responseCache),
|
|
||||||
cache.ClientWithTTL(3*time.Second),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache client", err)
|
|
||||||
}
|
|
||||||
reasonableDurationCacheClient, err := cache.NewClient(
|
|
||||||
cache.ClientWithAdapter(responseCache),
|
|
||||||
cache.ClientWithTTL(8*time.Second),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache client", err)
|
|
||||||
}
|
|
||||||
longerDurationCacheClient, err := cache.NewClient(
|
|
||||||
cache.ClientWithAdapter(responseCache),
|
|
||||||
cache.ClientWithTTL(3*time.Minute),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("unable to create web cache client", err)
|
|
||||||
}
|
|
||||||
// The primary web app.
|
// The primary web app.
|
||||||
http.HandleFunc("/", controllers.IndexHandler)
|
http.HandleFunc("/", controllers.IndexHandler)
|
||||||
|
|
||||||
|
@ -70,79 +35,41 @@ func Start() error {
|
||||||
http.HandleFunc("/admin/", middleware.RequireAdminAuth(controllers.IndexHandler))
|
http.HandleFunc("/admin/", middleware.RequireAdminAuth(controllers.IndexHandler))
|
||||||
|
|
||||||
// Images
|
// Images
|
||||||
http.HandleFunc("/thumbnail.jpg", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/thumbnail.jpg", controllers.GetThumbnail)
|
||||||
superShortCacheClient.Middleware(http.HandlerFunc(controllers.GetThumbnail)).ServeHTTP(rw, r)
|
http.HandleFunc("/preview.gif", controllers.GetPreview)
|
||||||
})
|
http.HandleFunc("/logo", controllers.GetLogo)
|
||||||
|
|
||||||
http.HandleFunc("/preview.gif", func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
superShortCacheClient.Middleware(http.HandlerFunc(controllers.GetPreview)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
http.HandleFunc("/logo", func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
longerDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetLogo)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Custom Javascript
|
// Custom Javascript
|
||||||
http.HandleFunc("/customjavascript", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/customjavascript", controllers.ServeCustomJavascript)
|
||||||
longerDurationCacheClient.Middleware(http.HandlerFunc(controllers.ServeCustomJavascript)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Return a single emoji image.
|
// Return a single emoji image.
|
||||||
http.HandleFunc(config.EmojiDir, func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(config.EmojiDir, controllers.GetCustomEmojiImage)
|
||||||
longerDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetCustomEmojiImage)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// return the logo
|
// return the logo
|
||||||
|
|
||||||
// return a logo that's compatible with external social networks
|
// return a logo that's compatible with external social networks
|
||||||
http.HandleFunc("/logo/external", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/logo/external", controllers.GetCompatibleLogo)
|
||||||
longerDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetCompatibleLogo)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// robots.txt
|
// robots.txt
|
||||||
http.HandleFunc("/robots.txt", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/robots.txt", controllers.GetRobotsDotTxt)
|
||||||
longerDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetRobotsDotTxt)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// status of the system
|
// status of the system
|
||||||
if enableCache {
|
http.HandleFunc("/api/status", controllers.GetStatus)
|
||||||
http.HandleFunc("/api/status", func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
superShortCacheClient.Middleware(http.HandlerFunc(controllers.GetStatus)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
http.HandleFunc("/api/status", controllers.GetStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
// custom emoji supported in the chat
|
// custom emoji supported in the chat
|
||||||
http.HandleFunc("/api/emoji", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/api/emoji", controllers.GetCustomEmojiList)
|
||||||
reasonableDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetCustomEmojiList)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// chat rest api
|
// chat rest api
|
||||||
if enableCache {
|
http.HandleFunc("/api/chat", middleware.RequireUserAccessToken(controllers.GetChatMessages))
|
||||||
http.HandleFunc("/api/chat", func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
superShortCacheClient.Middleware(middleware.RequireUserAccessToken(controllers.GetChatMessages))
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
http.HandleFunc("/api/chat", middleware.RequireUserAccessToken(controllers.GetChatMessages))
|
|
||||||
}
|
|
||||||
|
|
||||||
// web config api
|
// web config api
|
||||||
if enableCache {
|
http.HandleFunc("/api/config", controllers.GetWebConfig)
|
||||||
http.HandleFunc("/api/config", func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
superShortCacheClient.Middleware(http.HandlerFunc(controllers.GetWebConfig)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
http.HandleFunc("/api/config", controllers.GetWebConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the YP protocol data
|
// return the YP protocol data
|
||||||
http.HandleFunc("/api/yp", yp.GetYPResponse)
|
http.HandleFunc("/api/yp", yp.GetYPResponse)
|
||||||
|
|
||||||
// list of all social platforms
|
// list of all social platforms
|
||||||
http.HandleFunc("/api/socialplatforms", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/api/socialplatforms", controllers.GetAllSocialPlatforms)
|
||||||
reasonableDurationCacheClient.Middleware(http.HandlerFunc(controllers.GetAllSocialPlatforms)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// return the list of video variants available
|
// return the list of video variants available
|
||||||
http.HandleFunc("/api/video/variants", controllers.GetVideoStreamOutputVariants)
|
http.HandleFunc("/api/video/variants", controllers.GetVideoStreamOutputVariants)
|
||||||
|
@ -157,9 +84,7 @@ func Start() error {
|
||||||
http.HandleFunc("/api/remotefollow", controllers.RemoteFollow)
|
http.HandleFunc("/api/remotefollow", controllers.RemoteFollow)
|
||||||
|
|
||||||
// return followers
|
// return followers
|
||||||
http.HandleFunc("/api/followers", func(rw http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/api/followers", middleware.HandlePagination(controllers.GetFollowers))
|
||||||
reasonableDurationCacheClient.Middleware(middleware.HandlePagination(controllers.GetFollowers)).ServeHTTP(rw, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
// save client video playback metrics
|
// save client video playback metrics
|
||||||
http.HandleFunc("/api/metrics/playback", controllers.ReportPlaybackMetrics)
|
http.HandleFunc("/api/metrics/playback", controllers.ReportPlaybackMetrics)
|
||||||
|
|
|
@ -43,7 +43,7 @@ function start_owncast() {
|
||||||
go build -o owncast main.go
|
go build -o owncast main.go
|
||||||
|
|
||||||
echo "Running owncast..."
|
echo "Running owncast..."
|
||||||
./owncast -disableResponseCaching -database "$TEMP_DB" &
|
./owncast -database "$TEMP_DB" &
|
||||||
SERVER_PID=$!
|
SERVER_PID=$!
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue