Link rel preload boot data
This commit is contained in:
parent
9b6844449d
commit
4b4b2394a9
9 changed files with 180 additions and 80 deletions
24
server/gzip.go
Normal file
24
server/gzip.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var gzipWriterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return gzip.NewWriter(nil)
|
||||
},
|
||||
}
|
||||
|
||||
func getGzipWriter(w io.Writer) *gzip.Writer {
|
||||
gzw := gzipWriterPool.Get().(*gzip.Writer)
|
||||
gzw.Reset(w)
|
||||
return gzw
|
||||
}
|
||||
|
||||
func putGzipWriter(gzw *gzip.Writer) {
|
||||
gzw.Close()
|
||||
gzipWriterPool.Put(gzw)
|
||||
}
|
30
server/http.go
Normal file
30
server/http.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
func writeJSON(w http.ResponseWriter, r *http.Request, data easyjson.Marshaler) {
|
||||
json, err := easyjson.Marshal(data)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
fail(w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if len(json) > 1400 && strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
||||
w.Header().Set("Content-Encoding", "gzip")
|
||||
|
||||
gzw := getGzipWriter(w)
|
||||
gzw.Write(json)
|
||||
putGzipWriter(gzw)
|
||||
} else {
|
||||
w.Write(json)
|
||||
}
|
||||
}
|
|
@ -1,42 +1,75 @@
|
|||
<%! data *indexData, cssPath string, inlineScript string, scripts []string %>
|
||||
|
||||
<%% import "github.com/mailru/easyjson" %%>
|
||||
<%! data *indexData, cssPath string, inlineScript string, scripts []string, sw
|
||||
bool %> <%% import "github.com/mailru/easyjson" %%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#f0f0f0" />
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#222">
|
||||
<title>Dispatch</title>
|
||||
|
||||
<title>Dispatch</title>
|
||||
<% if sw { %>
|
||||
<link rel="preload" href="/data" as="fetch" crossorigin="anonymous" />
|
||||
<% } %>
|
||||
|
||||
<link rel="preload" href="/font/fontello.woff2?48901973" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="/font/RobotoMono-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="/font/Montserrat-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="/font/Montserrat-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="preload" href="/font/RobotoMono-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<script>
|
||||
<%== inlineScript %>
|
||||
</script>
|
||||
|
||||
<% if cssPath != "" { %>
|
||||
<link href="<%== cssPath %>" rel="stylesheet">
|
||||
<% } %>
|
||||
<link
|
||||
rel="preload"
|
||||
href="/font/fontello.woff2?48901973"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="/font/RobotoMono-Regular.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="/font/Montserrat-Regular.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="/font/Montserrat-Bold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="/font/RobotoMono-Bold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
|
||||
<link rel="icon" href="data:;base64,=">
|
||||
<% if cssPath != "" { %>
|
||||
<link href="<%== cssPath %>" rel="stylesheet" />
|
||||
<% } %>
|
||||
|
||||
<script><%== inlineScript %></script>
|
||||
</head>
|
||||
<link rel="icon" href="data:;base64,=" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<% if data != nil { %>
|
||||
<script id="env" type="application/json"><% easyjson.MarshalToWriter(data, w) %></script>
|
||||
<% } %>
|
||||
|
||||
<% for _, script := range scripts { %>
|
||||
<script src="<%== script %>"></script>
|
||||
<% } %>
|
||||
</body>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<% if data != nil { %>
|
||||
<script id="env" type="application/json">
|
||||
<% easyjson.MarshalToWriter(data, w) %>
|
||||
</script>
|
||||
<% } %> <% for _, script := range scripts { %>
|
||||
<script src="<%== script %>"></script>
|
||||
<% } %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,16 +7,20 @@ import (
|
|||
"github.com/mailru/easyjson"
|
||||
)
|
||||
|
||||
func IndexTemplate(w io.Writer, data *indexData, cssPath string, inlineScript string, scripts []string) error {
|
||||
io.WriteString(w, "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta name=\"theme-color\" content=\"#222\"><title>Dispatch</title><link rel=\"preload\" href=\"/font/fontello.woff2?48901973\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/RobotoMono-Regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/Montserrat-Regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/Montserrat-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/RobotoMono-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\">")
|
||||
func IndexTemplate(w io.Writer, data *indexData, cssPath string, inlineScript string, scripts []string, sw bool) error {
|
||||
io.WriteString(w, "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta name=\"theme-color\" content=\"#f0f0f0\"><title>Dispatch</title>")
|
||||
if sw {
|
||||
io.WriteString(w, "<link rel=\"preload\" href=\"/data\" as=\"fetch\" crossorigin=\"anonymous\">")
|
||||
}
|
||||
io.WriteString(w, "<script>")
|
||||
io.WriteString(w, inlineScript )
|
||||
io.WriteString(w, "</script><link rel=\"preload\" href=\"/font/fontello.woff2?48901973\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/RobotoMono-Regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/Montserrat-Regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/Montserrat-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\"><link rel=\"preload\" href=\"/font/RobotoMono-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\">")
|
||||
if cssPath != "" {
|
||||
io.WriteString(w, "<link href=\"")
|
||||
io.WriteString(w, cssPath )
|
||||
io.WriteString(w, "\" rel=\"stylesheet\">")
|
||||
}
|
||||
io.WriteString(w, "<link rel=\"icon\" href=\"data:;base64,=\"><script>")
|
||||
io.WriteString(w, inlineScript )
|
||||
io.WriteString(w, "</script></head><body><div id=\"root\"></div>")
|
||||
io.WriteString(w, "<link rel=\"icon\" href=\"data:;base64,=\"></head><body><div id=\"root\"></div>")
|
||||
if data != nil {
|
||||
io.WriteString(w, "<script id=\"env\" type=\"application/json\">")
|
||||
easyjson.MarshalToWriter(data, w)
|
||||
|
|
|
@ -83,6 +83,15 @@ func getIndexData(r *http.Request, path string, state *State) *indexData {
|
|||
}
|
||||
data.Channels = channels
|
||||
|
||||
referer, err := url.Parse(r.Header.Get("Referer"))
|
||||
if err == nil {
|
||||
server, channel := getTabFromPath(referer.EscapedPath())
|
||||
if isInChannel(channels, server, channel) {
|
||||
data.addUsersAndMessages(server, channel, state)
|
||||
return &data
|
||||
}
|
||||
}
|
||||
|
||||
server, channel := getTabFromPath(path)
|
||||
if isInChannel(channels, server, channel) {
|
||||
data.addUsersAndMessages(server, channel, state)
|
||||
|
|
|
@ -163,7 +163,7 @@ func (d *Dispatch) initFileServer() {
|
|||
|
||||
serviceWorker = decompressedAsset("sw.js")
|
||||
hash.Reset()
|
||||
IndexTemplate(hash, nil, indexStylesheet, inlineScriptSW, indexScripts)
|
||||
IndexTemplate(hash, nil, indexStylesheet, inlineScriptSW, indexScripts, true)
|
||||
indexHash := base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||
|
||||
serviceWorker = append(serviceWorker, []byte(`
|
||||
|
@ -324,6 +324,7 @@ func (d *Dispatch) serveIndex(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-Frame-Options", "deny")
|
||||
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
w.Header().Set("Referrer-Policy", "same-origin")
|
||||
|
||||
if hstsHeader != "" {
|
||||
w.Header().Set("Strict-Transport-Security", hstsHeader)
|
||||
|
@ -339,11 +340,11 @@ func (d *Dispatch) serveIndex(w http.ResponseWriter, r *http.Request) {
|
|||
if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
||||
w.Header().Set("Content-Encoding", "gzip")
|
||||
|
||||
gzw := gzip.NewWriter(w)
|
||||
IndexTemplate(gzw, data, indexStylesheet, inline, indexScripts)
|
||||
gzw.Close()
|
||||
gzw := getGzipWriter(w)
|
||||
IndexTemplate(gzw, data, indexStylesheet, inline, indexScripts, sw)
|
||||
putGzipWriter(gzw)
|
||||
} else {
|
||||
IndexTemplate(w, data, indexStylesheet, inline, indexScripts)
|
||||
IndexTemplate(w, data, indexStylesheet, inline, indexScripts, sw)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/khlieng/dispatch/pkg/letsencrypt"
|
||||
"github.com/khlieng/dispatch/pkg/session"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
@ -183,9 +182,9 @@ func (d *Dispatch) serve(w http.ResponseWriter, r *http.Request) {
|
|||
d.upgradeWS(w, r, state)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/data") {
|
||||
state := d.handleAuth(w, r, false, false)
|
||||
data := getIndexData(r, r.URL.EscapedPath()[5:], state)
|
||||
data := getIndexData(r, "/", state)
|
||||
|
||||
easyjson.MarshalToHTTPResponseWriter(data, w)
|
||||
writeJSON(w, r, data)
|
||||
} else {
|
||||
d.serveFiles(w, r)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue