Rename to StyleSheet and precache CSS bytes

If there is a custom CSS file specified and usable (it exists and is
readable), we precache it on server startup (for every host). This
increase the request performance and reduce IO-load slightly.
This commit is contained in:
Aaron Fischer 2021-07-09 22:15:35 +02:00
parent 83453281bc
commit 8654f0ca1b
3 changed files with 28 additions and 20 deletions

View file

@ -81,9 +81,9 @@ Set this option to `true` to disable this feature.
Pages are converted automatically by [gmitohtml](https://code.rocketnine.space/tslocum/gmitohtml). Pages are converted automatically by [gmitohtml](https://code.rocketnine.space/tslocum/gmitohtml).
## Styles ## StyleSheet
Specify a custom CSS styles file if you want to override the default. This only Specify a custom CSS stylesheet file if you want to override the default. This only
affects the `HTTPS` protocol (obviously). affects the `HTTPS` protocol (obviously).
### DisableSize ### DisableSize
@ -228,7 +228,7 @@ hosts:
gemini.rocks: gemini.rocks:
cert: /srv/gemini.rocks/data/cert.crt cert: /srv/gemini.rocks/data/cert.crt
key: /srv/gemini.rocks/data/cert.key key: /srv/gemini.rocks/data/cert.key
styles: /srv/gemini.rocks/styles.css # Custom CSS styles stylesheet: /srv/gemini.rocks/styles.css # Custom CSS stylesheet
paths: paths:
- -
path: ^/.*\.php$ path: ^/.*\.php$

View file

@ -67,7 +67,7 @@ type hostConfig struct {
Paths []*pathConfig Paths []*pathConfig
// Custom CSS styles. If specified, it will be used for all paths in that host/domain. // Custom CSS styles. If specified, it will be used for all paths in that host/domain.
Styles string StyleSheet string
cert *tls.Certificate cert *tls.Certificate
} }
@ -87,6 +87,8 @@ type serverConfig struct {
const cacheUnset = -1965 const cacheUnset = -1965
var customCSS = make(map[string][]byte)
var config *serverConfig var config *serverConfig
func readconfig(configPath string) error { func readconfig(configPath string) error {
@ -213,6 +215,21 @@ func readconfig(configPath string) error {
} }
host.cert = &cert host.cert = &cert
// Custom CSS stylesheets are precached in customCSS and used on HTTPS requests.
if host.StyleSheet != "" {
_, err := os.Stat(host.StyleSheet)
if os.IsNotExist(err) {
log.Printf("custom stylesheet '%v' not found, ignore it.", host.StyleSheet)
} else {
cssBytes, err := ioutil.ReadFile(host.StyleSheet)
if err != nil {
log.Printf("problems with stylesheet '%v': %v", host.StyleSheet, err.Error())
} else {
customCSS[hostname] = cssBytes
}
}
}
for _, serve := range host.Paths { for _, serve := range host.Paths {
if serve.Path == "" { if serve.Path == "" {
log.Fatal("a path must be specified in each serve entry") log.Fatal("a path must be specified in each serve entry")

View file

@ -31,22 +31,6 @@ func serveHTTPS(w http.ResponseWriter, r *http.Request) (int, int64, string) {
http.Redirect(w, r, u.String(), status) http.Redirect(w, r, u.String(), status)
return status, -1, "" return status, -1, ""
} else if r.URL.Path == "/assets/style.css" { } else if r.URL.Path == "/assets/style.css" {
// Do we have a custom CSS file? If so, we use this instead.
styleFilepath := config.Hosts[r.URL.Hostname()].Styles
if styleFilepath != "" {
_, err := os.Stat(styleFilepath)
if os.IsNotExist(err) {
http.Error(w, "Custom styles not found", http.StatusNotFound)
return http.StatusNotFound, -1, ""
}
cssBytes, err = ioutil.ReadFile(styleFilepath)
if err != nil {
http.Error(w, "Cannot process custom styles", http.StatusInternalServerError)
return http.StatusInternalServerError, -1, ""
}
}
status := http.StatusOK status := http.StatusOK
w.Header().Set("Content-Type", cssType) w.Header().Set("Content-Type", cssType)
w.WriteHeader(status) w.WriteHeader(status)
@ -55,6 +39,13 @@ func serveHTTPS(w http.ResponseWriter, r *http.Request) (int, int64, string) {
return status, 0, "" return status, 0, ""
} }
// Do we have a custom CSS file? If so, we use this instead.
if css, found := customCSS[r.URL.Hostname()]; found {
w.Write(css)
return status, int64(len(css)), ""
}
// Default CSS
w.Write(cssBytes) w.Write(cssBytes)
return status, int64(len(cssBytes)), "" return status, int64(len(cssBytes)), ""
} }