Various changes (SRI for JS, HTTP server init, ect.)

This commit is contained in:
Jan-Lukas Else 2021-04-02 10:28:04 +02:00
parent 7f8ea2d94b
commit 33684a7940
7 changed files with 84 additions and 46 deletions

11
go.mod
View File

@ -8,7 +8,7 @@ require (
github.com/andybalholm/cascadia v1.2.0 // indirect
github.com/araddon/dateparse v0.0.0-20210207001429-0eec95c9db7e
github.com/boombuler/barcode v1.0.1 // indirect
github.com/caddyserver/certmagic v0.12.0
github.com/caddyserver/certmagic v0.13.0
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
github.com/dgraph-io/ristretto v0.0.4-0.20210311064603-e4f298c8aa88
@ -31,12 +31,10 @@ require (
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.4 // indirect
github.com/lib/pq v1.9.0 // indirect
github.com/libdns/libdns v0.2.0 // indirect
github.com/lopezator/migrator v0.3.0
github.com/magiconair/properties v1.8.5 // indirect
github.com/mattn/go-sqlite3 v1.14.6
github.com/mholt/acmez v0.1.3 // indirect
github.com/microcosm-cc/bluemonday v1.0.4
github.com/microcosm-cc/bluemonday v1.0.5
github.com/miekg/dns v1.1.41 // indirect
github.com/mitchellh/go-server-timing v1.0.1
github.com/mitchellh/mapstructure v1.4.1 // indirect
@ -60,10 +58,11 @@ require (
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
golang.org/x/mod v0.4.1 // indirect
golang.org/x/net v0.0.0-20210326060303-6b1517762897 // indirect
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/text v0.3.5 // indirect
golang.org/x/text v0.3.6 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

23
go.sum
View File

@ -43,8 +43,8 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBW
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
github.com/caddyserver/certmagic v0.12.0 h1:1f7kxykaJkOVVpXJ8ZrC6RAO5F6+kKm9U7dBFbLNeug=
github.com/caddyserver/certmagic v0.12.0/go.mod h1:tr26xh+9fY5dN0J6IPAlMj07qpog22PJKa7Nw7j835U=
github.com/caddyserver/certmagic v0.13.0 h1:ky0rntZvIFiUKFdIikYxj31WN+Ts0Od6Wjz83iTzxfc=
github.com/caddyserver/certmagic v0.13.0/go.mod h1:dNOzF4iOB7H9E51xTooMB90vs+2XNVtpnx0liQNsQY4=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
@ -210,7 +210,6 @@ github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR7
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libdns/libdns v0.1.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/lopezator/migrator v0.3.0 h1:VW/rR+J8NYwPdkBxjrFdjwejpgvP59LbmANJxXuNbuk=
@ -230,11 +229,10 @@ github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGw
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mholt/acmez v0.1.1/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg=
github.com/microcosm-cc/bluemonday v1.0.4/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
github.com/microcosm-cc/bluemonday v1.0.5 h1:cF59UCKMmmUgqN1baLvqU/B1ZsMori+duLVTLpgiG3w=
github.com/microcosm-cc/bluemonday v1.0.5/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
@ -419,8 +417,8 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -455,8 +453,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -464,8 +463,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

47
http.go
View File

@ -4,6 +4,7 @@ import (
"compress/flate"
"fmt"
"log"
"net"
"net/http"
"net/url"
"strconv"
@ -74,30 +75,56 @@ func startServer() (err error) {
log.Println("Tor failed:", torErr.Error())
}()
}
// Start HTTP(s) server
localAddress := ":" + strconv.Itoa(appConfig.Server.Port)
// Start server
s := &http.Server{
Handler: finalHandler,
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
}
if appConfig.Server.PublicHTTPS {
// Configure
certmagic.Default.Storage = &certmagic.FileStorage{Path: "data/https"}
certmagic.DefaultACME.Agreed = true
certmagic.DefaultACME.Email = appConfig.Server.LetsEncryptMail
certmagic.DefaultACME.CA = certmagic.LetsEncryptProductionCA
// Start HTTP server for TLS verification and redirect
httpServer := &http.Server{
Addr: ":http",
Handler: http.HandlerFunc(redirectToHttps),
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
}
go func() {
if err := httpServer.ListenAndServe(); err != nil {
log.Println("Failed to start HTTP server:", err.Error())
}
}()
// Start HTTPS
s.Addr = ":https"
hosts := []string{appConfig.Server.publicHostname}
if appConfig.Server.shortPublicHostname != "" {
hosts = append(hosts, appConfig.Server.shortPublicHostname)
}
err = certmagic.HTTPS(hosts, finalHandler)
} else {
s := &http.Server{
Addr: localAddress,
Handler: finalHandler,
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
listener, e := certmagic.Listen(hosts)
if e != nil {
return e
}
err = s.Serve(listener)
} else {
s.Addr = ":" + strconv.Itoa(appConfig.Server.Port)
err = s.ListenAndServe()
}
return
}
func redirectToHttps(w http.ResponseWriter, r *http.Request) {
requestHost, _, err := net.SplitHostPort(r.Host)
if err != nil {
requestHost = r.Host
}
w.Header().Set("Connection", "close")
http.Redirect(w, r, fmt.Sprintf("https://%s%s", requestHost, r.URL.RequestURI()), http.StatusMovedPermanently)
}
func reloadRouter() error {
h, err := buildDynamicRouter()
if err != nil {

View File

@ -116,8 +116,9 @@ func initRendering() error {
}
return d.Before(b)
},
"asset": assetFileName,
"string": getTemplateStringVariant,
"asset": assetFileName,
"assetsri": assetSRI,
"string": getTemplateStringVariant,
"include": func(templateName string, data ...interface{}) (template.HTML, error) {
if len(data) == 0 || len(data) > 2 {
return "", errors.New("wrong argument count")

View File

@ -2,7 +2,10 @@ package main
import (
"crypto/sha1"
"crypto/sha512"
"encoding/base64"
"fmt"
"io"
"mime"
"net/http"
"os"
@ -18,6 +21,7 @@ var assetFiles map[string]*assetFile = map[string]*assetFile{}
type assetFile struct {
contentType string
sri string
body []byte
}
@ -41,37 +45,41 @@ func initTemplateAssets() (err error) {
}
func compileAsset(name string) (string, error) {
originalContent, err := os.ReadFile(name)
content, err := os.ReadFile(name)
if err != nil {
return "", err
}
ext := path.Ext(name)
var compiledContent []byte
compiledExt := ext
switch ext {
case ".js":
compiledContent, err = minifier.Bytes("application/javascript", originalContent)
content, err = minifier.Bytes("application/javascript", content)
if err != nil {
return "", err
}
case ".css":
compiledContent, err = minifier.Bytes("text/css", originalContent)
content, err = minifier.Bytes("text/css", content)
if err != nil {
return "", err
}
default:
// Just copy the file
compiledContent = originalContent
// Do nothing
}
sha := sha1.New()
if _, err := sha.Write(compiledContent); err != nil {
// Hashes
sha1Hash := sha1.New()
sha512Hash := sha512.New()
if _, err := io.MultiWriter(sha1Hash, sha512Hash).Write(content); err != nil {
return "", err
}
hash := fmt.Sprintf("%x", sha.Sum(nil))
compiledFileName := hash + compiledExt
// File name
compiledFileName := fmt.Sprintf("%x", sha1Hash.Sum(nil)) + compiledExt
// SRI
sriHash := fmt.Sprintf("sha512-%s", base64.StdEncoding.EncodeToString(sha512Hash.Sum(nil)))
// Create struct
assetFiles[compiledFileName] = &assetFile{
contentType: mime.TypeByExtension(compiledExt),
body: compiledContent,
sri: sriHash,
body: content,
}
return compiledFileName, err
}
@ -81,6 +89,10 @@ func assetFileName(fileName string) string {
return "/" + assetFileNames[fileName]
}
func assetSRI(fileName string) string {
return assetFiles[assetFileNames[fileName]].sri
}
func allAssetPaths() []string {
var paths []string
for _, name := range assetFileNames {

View File

@ -2,7 +2,7 @@ package main
import (
"os"
"path"
"path/filepath"
"gopkg.in/yaml.v3"
)
@ -21,14 +21,14 @@ func initTemplateStrings() error {
}
for _, variant := range variants {
variantStrings := map[string]string{}
fileContent, err := os.ReadFile(path.Join(stringsDir, variant+variantFileExt))
f, err := os.Open(filepath.Join(stringsDir, variant+variantFileExt))
if err != nil {
if os.IsNotExist(err) {
continue
}
return err
}
err = yaml.Unmarshal(fileContent, variantStrings)
err = yaml.NewDecoder(f).Decode(variantStrings)
if err != nil {
return err
}

View File

@ -2,8 +2,8 @@
<div class="p flex" id="post-actions">
<a href="https://www.addtoany.com/share#url={{ absolute .Data.Path }}{{ with title .Data }}&title={{ . }}{{ end }}" target="_blank" rel="nofollow noopener noreferrer" class="button">{{ string .Blog.Lang "share" }}</a>&nbsp;
<a id="translateBtn" href="https://translate.google.com/translate?u={{ absolute .Data.Path }}" target="_blank" rel="nofollow noopener noreferrer" class="button">{{ string .Blog.Lang "translate" }}</a>&nbsp;
<script defer src="{{ asset "js/translate.js" }}"></script>
<script defer src="{{ asset "js/translate.js" }}" integrity="{{ assetsri "js/translate.js" }}"></script>
<button id="speakBtn" class="hide" data-speak="{{ string .Blog.Lang "speak" }}" data-stopspeak="{{ string .Blog.Lang "stopspeak" }}"></button>
<script defer src="{{ asset "js/speak.js" }}"></script>
<script defer src="{{ asset "js/speak.js" }}" integrity="{{ assetsri "js/speak.js" }}"></script>
</div>
{{ end }}