@@ -29,6 +29,7 @@ type HTTP struct {
|
||||
Addr string
|
||||
Namespace string
|
||||
Root string
|
||||
CacheTTL int
|
||||
}
|
||||
|
||||
// GRPC defines the available grpc configuration.
|
||||
|
||||
@@ -57,6 +57,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
EnvVars: []string{"ACCOUNTS_HTTP_ROOT"},
|
||||
Destination: &cfg.HTTP.Root,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "http-cache-ttl",
|
||||
Value: 604800, // 7 days
|
||||
Usage: "Set the static assets caching duration in seconds",
|
||||
EnvVars: []string{"ACCOUNTS_CACHE_TTL"},
|
||||
Destination: &cfg.HTTP.CacheTTL,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-namespace",
|
||||
Value: "com.owncloud.api",
|
||||
|
||||
@@ -29,7 +29,7 @@ func Server(opts ...Option) http.Service {
|
||||
|
||||
mux.Use(middleware.RealIP)
|
||||
mux.Use(middleware.RequestID)
|
||||
mux.Use(middleware.Cache)
|
||||
mux.Use(middleware.NoCache)
|
||||
mux.Use(middleware.Cors)
|
||||
mux.Use(middleware.Secure)
|
||||
mux.Use(middleware.ExtractAccountUUID(
|
||||
@@ -52,6 +52,7 @@ func Server(opts ...Option) http.Service {
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
),
|
||||
options.Config.HTTP.CacheTTL,
|
||||
))
|
||||
|
||||
mux.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Change: Caching for static web assets
|
||||
|
||||
Tags: accounts, settings, web
|
||||
|
||||
We now set http caching headers for static web assets, so that they don't get force-reloaded on each request. The max-age for the caching is configurable and defaults to 7 days. The last modified date of the assets is set to the service start date, so that a service restart results in cache invalidation.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/866
|
||||
@@ -58,7 +58,7 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
svc.Middleware(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.NoCache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
|
||||
@@ -20,6 +20,7 @@ type HTTP struct {
|
||||
Addr string
|
||||
Root string
|
||||
Namespace string
|
||||
CacheTTL int
|
||||
}
|
||||
|
||||
// Tracing defines the available tracing configuration.
|
||||
|
||||
@@ -136,6 +136,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
EnvVars: []string{"PHOENIX_NAMESPACE"},
|
||||
Destination: &cfg.HTTP.Namespace,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "http-cache-ttl",
|
||||
Value: 604800, // 7 days
|
||||
Usage: "Set the static assets caching duration in seconds",
|
||||
EnvVars: []string{"PHOENIX_CACHE_TTL"},
|
||||
Destination: &cfg.HTTP.CacheTTL,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "asset-path",
|
||||
Value: "",
|
||||
|
||||
@@ -28,7 +28,7 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
svc.Middleware(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.NoCache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
phoenixmid.SilentRefresh,
|
||||
|
||||
@@ -2,10 +2,13 @@ package svc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/owncloud/ocis/ocis-phoenix/pkg/assets"
|
||||
@@ -39,7 +42,7 @@ func NewService(opts ...Option) Service {
|
||||
|
||||
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
r.Get("/config.json", svc.Config)
|
||||
r.Mount("/", svc.Static())
|
||||
r.Mount("/", svc.Static(options.Config.HTTP.CacheTTL))
|
||||
})
|
||||
|
||||
return svc
|
||||
@@ -124,7 +127,7 @@ func (p Phoenix) Config(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Static simply serves all static files.
|
||||
func (p Phoenix) Static() http.HandlerFunc {
|
||||
func (p Phoenix) Static(ttl int) http.HandlerFunc {
|
||||
rootWithSlash := p.config.HTTP.Root
|
||||
|
||||
if !strings.HasSuffix(rootWithSlash, "/") {
|
||||
@@ -141,7 +144,10 @@ func (p Phoenix) Static() http.HandlerFunc {
|
||||
),
|
||||
)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// we don't have a last modification date of the static assets, so we use the service start date
|
||||
lastModified := time.Now().UTC().Format(http.TimeFormat)
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if rootWithSlash != "/" && r.URL.Path == p.config.HTTP.Root {
|
||||
http.Redirect(
|
||||
w,
|
||||
@@ -162,6 +168,10 @@ func (p Phoenix) Static() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%s", strconv.Itoa(ttl)))
|
||||
w.Header().Set("Last-Modified", lastModified)
|
||||
w.Header().Del("Expires")
|
||||
|
||||
static.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Cache writes required cache headers to all requests.
|
||||
func Cache(next http.Handler) http.Handler {
|
||||
// NoCache writes required cache headers to all requests.
|
||||
func NoCache(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
|
||||
w.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Static is a middleware that serves static assets.
|
||||
func Static(root string, fs http.FileSystem) func(http.Handler) http.Handler {
|
||||
func Static(root string, fs http.FileSystem, ttl int) func(http.Handler) http.Handler {
|
||||
if !strings.HasSuffix(root, "/") {
|
||||
root = root + "/"
|
||||
}
|
||||
@@ -19,6 +22,9 @@ func Static(root string, fs http.FileSystem) func(http.Handler) http.Handler {
|
||||
),
|
||||
)
|
||||
|
||||
// we don't have a last modification date of the static assets, so we use the service start date
|
||||
lastModified := time.Now().UTC().Format(http.TimeFormat)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, path.Join(root, "api")) {
|
||||
@@ -27,6 +33,9 @@ func Static(root string, fs http.FileSystem) func(http.Handler) http.Handler {
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
http.NotFound(w, r)
|
||||
} else {
|
||||
w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%s", strconv.Itoa(ttl)))
|
||||
w.Header().Set("Last-Modified", lastModified)
|
||||
w.Header().Del("Expires")
|
||||
static.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewService(opts ...Option) *http.Server {
|
||||
Handler: alice.New(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.NoCache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
|
||||
@@ -26,7 +26,7 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
svc.Middleware(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.NoCache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
|
||||
@@ -20,6 +20,7 @@ type HTTP struct {
|
||||
Addr string
|
||||
Namespace string
|
||||
Root string
|
||||
CacheTTL int
|
||||
}
|
||||
|
||||
// GRPC defines the available grpc configuration.
|
||||
|
||||
@@ -136,6 +136,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
EnvVars: []string{"SETTINGS_HTTP_ROOT"},
|
||||
Destination: &cfg.HTTP.Root,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "http-cache-ttl",
|
||||
Value: 604800, // 7 days
|
||||
Usage: "Set the static assets caching duration in seconds",
|
||||
EnvVars: []string{"SETTINGS_CACHE_TTL"},
|
||||
Destination: &cfg.HTTP.CacheTTL,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-addr",
|
||||
Value: "0.0.0.0:9191",
|
||||
|
||||
@@ -37,7 +37,7 @@ func Server(opts ...Option) http.Service {
|
||||
|
||||
mux.Use(middleware.RealIP)
|
||||
mux.Use(middleware.RequestID)
|
||||
mux.Use(middleware.Cache)
|
||||
mux.Use(middleware.NoCache)
|
||||
mux.Use(middleware.Cors)
|
||||
mux.Use(middleware.Secure)
|
||||
mux.Use(middleware.ExtractAccountUUID(
|
||||
@@ -60,6 +60,7 @@ func Server(opts ...Option) http.Service {
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
),
|
||||
options.Config.HTTP.CacheTTL,
|
||||
))
|
||||
|
||||
mux.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
|
||||
@@ -26,7 +26,7 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
svc.Middleware(
|
||||
middleware.RealIP,
|
||||
middleware.RequestID,
|
||||
middleware.Cache,
|
||||
middleware.NoCache,
|
||||
middleware.Cors,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
|
||||
Reference in New Issue
Block a user