Update StyleSheet implementation

This commit is contained in:
Trevor Slocum 2021-07-10 09:13:39 -07:00
parent 9cd235c469
commit 3500533ecf
7 changed files with 38 additions and 35 deletions

View file

@ -91,18 +91,19 @@ certbot certonly --config-dir /home/www/certs \
Provide the path to the certificate file at `certs/live/$DOMAIN/fullchain.pem` Provide the path to the certificate file at `certs/live/$DOMAIN/fullchain.pem`
and the private key file at `certs/live/$DOMAIN/privkey.pem` to twins. and the private key file at `certs/live/$DOMAIN/privkey.pem` to twins.
## DisableHTTPS ### StyleSheet
Provide the path to a style sheet to serve instead of the default style sheet.
This option only applies when serving HTTPS connections.
### DisableHTTPS
Pages are also available via HTTPS on the same port by default. Pages are also available via HTTPS on the same port by default.
Set this option to `true` to disable this feature. 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).
## StyleSheet
Specify a custom CSS stylesheet file if you want to override the default. This only
affects the `HTTPS` protocol (obviously).
### DisableSize ### DisableSize
The size of the response body is included in the media type header by default. The size of the response body is included in the media type header by default.
@ -245,7 +246,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
stylesheet: /srv/gemini.rocks/styles.css # Custom CSS stylesheet stylesheet: /srv/gemini.rocks/style.css
paths: paths:
- -
path: ^/.*\.php$ path: ^/.*\.php$

View file

@ -70,6 +70,7 @@ type hostConfig struct {
StyleSheet string StyleSheet string
cert *tls.Certificate cert *tls.Certificate
css []byte
} }
type serverConfig struct { type serverConfig struct {
@ -87,8 +88,6 @@ 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 {
@ -219,13 +218,12 @@ func readconfig(configPath string) error {
if host.StyleSheet != "" { if host.StyleSheet != "" {
_, err := os.Stat(host.StyleSheet) _, err := os.Stat(host.StyleSheet)
if os.IsNotExist(err) { if os.IsNotExist(err) {
log.Printf("custom stylesheet '%v' not found, ignore it.", host.StyleSheet) log.Printf("error: stylesheet '%s' not found", host.StyleSheet)
} else { } else {
cssBytes, err := ioutil.ReadFile(host.StyleSheet) host.css, err = ioutil.ReadFile(host.StyleSheet)
if err != nil { if err != nil {
log.Printf("problems with stylesheet '%v': %v", host.StyleSheet, err.Error()) host.css = nil
} else { log.Printf("error: failed to read stylesheet %s: %s", host.StyleSheet, err)
customCSS[hostname] = cssBytes
} }
} }
} }

2
go.mod
View file

@ -7,6 +7,6 @@ require (
github.com/h2non/filetype v1.1.1 github.com/h2non/filetype v1.1.1
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/yookoala/gofast v0.6.0 github.com/yookoala/gofast v0.6.0
golang.org/x/tools v0.1.2 // indirect golang.org/x/tools v0.1.4 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
) )

4
go.sum
View file

@ -41,8 +41,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200908211811-12e1bf57a112/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200908211811-12e1bf57a112/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= golang.org/x/tools v0.1.4 h1:cVngSRcfgyZCzys3KYOpCFa+4dqX/Oub9tAq00ttGVs=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View file

@ -14,12 +14,14 @@ func init() {
} }
var quiet bool var quiet bool
var debug bool
func main() { func main() {
log.SetFlags(0) log.SetFlags(0)
configFile := flag.String("config", "", "path to configuration file") configFile := flag.String("config", "", "path to configuration file")
flag.BoolVar(&quiet, "quiet", false, "do not print access log") flag.BoolVar(&quiet, "quiet", false, "do not print access log")
flag.BoolVar(&debug, "debug", false, "print debug information")
flag.Parse() flag.Parse()
if *configFile == "" { if *configFile == "" {

View file

@ -30,24 +30,6 @@ func serveHTTPS(w http.ResponseWriter, r *http.Request) (int, int64, string) {
status := http.StatusTemporaryRedirect status := http.StatusTemporaryRedirect
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" {
status := http.StatusOK
w.Header().Set("Content-Type", cssType)
w.WriteHeader(status)
if r.Method == "HEAD" {
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)
return status, int64(len(cssBytes)), ""
} }
pathBytes := []byte(r.URL.Path) pathBytes := []byte(r.URL.Path)
@ -57,6 +39,23 @@ func serveHTTPS(w http.ResponseWriter, r *http.Request) (int, int64, string) {
} }
if host, ok := config.Hosts[r.URL.Hostname()]; ok { if host, ok := config.Hosts[r.URL.Hostname()]; ok {
if strings.HasSuffix(r.URL.Path, "/assets/style.css") {
status := http.StatusOK
w.Header().Set("Content-Type", cssType)
w.WriteHeader(status)
if r.Method == "HEAD" {
return status, 0, ""
}
if host.css != nil {
w.Write(host.css)
} else {
w.Write(cssBytes)
}
return status, int64(len(cssBytes)), ""
}
for _, serve := range host.Paths { for _, serve := range host.Paths {
matchedRegexp := serve.r != nil && serve.r.Match(pathBytes) matchedRegexp := serve.r != nil && serve.r.Match(pathBytes)
matchedPrefix := serve.r == nil && strings.HasPrefix(r.URL.Path, serve.Path) matchedPrefix := serve.r == nil && strings.HasPrefix(r.URL.Path, serve.Path)

View file

@ -351,6 +351,9 @@ func handleConn(c *tls.Conn) {
if err == io.EOF { if err == io.EOF {
break break
} else if err != nil || n != 1 { } else if err != nil || n != 1 {
if debug {
log.Printf("error: failed to read client: %s", err)
}
return return
} }