Server push is back. But only for Chrome and Firefox.
Added the DisableServerPush and EnableCDNPush config.json settings.
This commit is contained in:
parent
167bb230b4
commit
af9a56a9a9
|
@ -10,10 +10,10 @@ import (
|
|||
"github.com/Azareal/Gosora/common/phrases"
|
||||
)
|
||||
|
||||
type HResource struct {
|
||||
/*type HResource struct {
|
||||
Name string
|
||||
Hash string
|
||||
}
|
||||
}*/
|
||||
|
||||
// TODO: Allow resources in spots other than /static/ and possibly even external domains (e.g. CDNs)
|
||||
// TODO: Preload Trumboyg on Cosora on the forum list
|
||||
|
@ -21,11 +21,11 @@ type Header struct {
|
|||
Title string
|
||||
//Title []byte // Experimenting with []byte for increased efficiency, let's avoid converting too many things to []byte, as it involves a lot of extra boilerplate
|
||||
NoticeList []string
|
||||
Scripts []HResource
|
||||
PreScriptsAsync []HResource
|
||||
ScriptsAsync []HResource
|
||||
Scripts []string
|
||||
PreScriptsAsync []string
|
||||
ScriptsAsync []string
|
||||
//Preload []string
|
||||
Stylesheets []HResource
|
||||
Stylesheets []string
|
||||
Widgets PageWidgets
|
||||
Site *site
|
||||
Settings SettingMap
|
||||
|
@ -51,40 +51,48 @@ type Header struct {
|
|||
|
||||
func (header *Header) AddScript(name string) {
|
||||
fname := "/static/" + name
|
||||
var hash string
|
||||
var oname string
|
||||
if fname[0] == '/' && fname[1] != '/' {
|
||||
file, ok := StaticFiles.Get(fname)
|
||||
if ok {
|
||||
hash = file.Sha256
|
||||
oname = name + "?h=" + file.Sha256
|
||||
}
|
||||
}
|
||||
//log.Print("name:", name)
|
||||
//log.Print("hash:", hash)
|
||||
header.Scripts = append(header.Scripts, HResource{name, hash})
|
||||
if oname == "" {
|
||||
oname = name
|
||||
}
|
||||
//log.Print("oname:", oname)
|
||||
header.Scripts = append(header.Scripts, oname)
|
||||
}
|
||||
|
||||
func (header *Header) AddPreScriptAsync(name string) {
|
||||
fname := "/static/" + name
|
||||
var hash string
|
||||
var oname string
|
||||
if fname[0] == '/' && fname[1] != '/' {
|
||||
file, ok := StaticFiles.Get(fname)
|
||||
if ok {
|
||||
hash = file.Sha256
|
||||
oname = name + "?h=" + file.Sha256
|
||||
}
|
||||
}
|
||||
header.PreScriptsAsync = append(header.PreScriptsAsync, HResource{name, hash})
|
||||
if oname == "" {
|
||||
oname = name
|
||||
}
|
||||
header.PreScriptsAsync = append(header.PreScriptsAsync, oname)
|
||||
}
|
||||
|
||||
func (header *Header) AddScriptAsync(name string) {
|
||||
fname := "/static/" + name
|
||||
var hash string
|
||||
var oname string
|
||||
if fname[0] == '/' && fname[1] != '/' {
|
||||
file, ok := StaticFiles.Get(fname)
|
||||
if ok {
|
||||
hash = file.Sha256
|
||||
oname = name + "?h=" + file.Sha256
|
||||
}
|
||||
}
|
||||
header.ScriptsAsync = append(header.ScriptsAsync, HResource{name, hash})
|
||||
if oname == "" {
|
||||
oname = name
|
||||
}
|
||||
header.ScriptsAsync = append(header.ScriptsAsync, oname)
|
||||
}
|
||||
|
||||
/*func (header *Header) Preload(name string) {
|
||||
|
@ -93,14 +101,17 @@ func (header *Header) AddScriptAsync(name string) {
|
|||
|
||||
func (header *Header) AddSheet(name string) {
|
||||
fname := "/static/" + name
|
||||
var hash string
|
||||
var oname string
|
||||
if fname[0] == '/' && fname[1] != '/' {
|
||||
file, ok := StaticFiles.Get(fname)
|
||||
if ok {
|
||||
hash = file.Sha256
|
||||
oname = name + "?h=" + file.Sha256
|
||||
}
|
||||
}
|
||||
header.Stylesheets = append(header.Stylesheets, HResource{name, hash})
|
||||
if oname == "" {
|
||||
oname = name
|
||||
}
|
||||
header.Stylesheets = append(header.Stylesheets, oname)
|
||||
}
|
||||
|
||||
func (header *Header) AddNotice(name string) {
|
||||
|
|
|
@ -90,6 +90,8 @@ type config struct {
|
|||
DisableLiveTopicList bool
|
||||
DisableJSAntispam bool
|
||||
//LooseCSP bool
|
||||
DisableServerPush bool
|
||||
EnableCDNPush bool
|
||||
|
||||
Noavatar string // ? - Move this into the settings table?
|
||||
ItemsPerPage int // ? - Move this into the settings table?
|
||||
|
|
|
@ -89,14 +89,14 @@ var Template_account_handle = genIntTmpl("account")
|
|||
|
||||
func tmplInitUsers() (User, User, User) {
|
||||
avatar, microAvatar := BuildAvatar(62, "")
|
||||
user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", "", "", 0, 0, 0, "0.0.0.0.0", 0}
|
||||
user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", "", "", 0, 0, 0, "0.0.0.0.0", "", 0}
|
||||
|
||||
// TODO: Do a more accurate level calculation for this?
|
||||
avatar, microAvatar = BuildAvatar(1, "")
|
||||
user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 58, 1000, 0, "127.0.0.1", 0}
|
||||
user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 58, 1000, 0, "127.0.0.1", "", 0}
|
||||
|
||||
avatar, microAvatar = BuildAvatar(2, "")
|
||||
user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 42, 900, 0, "::1", 0}
|
||||
user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 42, 900, 0, "::1", "", 0}
|
||||
return user, user2, user3
|
||||
}
|
||||
|
||||
|
@ -108,10 +108,10 @@ func tmplInitHeaders(user User, user2 User, user3 User) (*Header, *Header, *Head
|
|||
Theme: Themes[DefaultThemeBox.Load().(string)],
|
||||
CurrentUser: user,
|
||||
NoticeList: []string{"test"},
|
||||
Stylesheets: []HResource{HResource{"panel.css", "d"}},
|
||||
Scripts: []HResource{HResource{"whatever.js", "d"}},
|
||||
PreScriptsAsync: []HResource{HResource{"whatever.js", "d"}},
|
||||
ScriptsAsync: []HResource{HResource{"whatever.js", "d"}},
|
||||
Stylesheets: []string{"panel.css"},
|
||||
Scripts: []string{"whatever.js"},
|
||||
PreScriptsAsync: []string{"whatever.js"},
|
||||
ScriptsAsync: []string{"whatever.js"},
|
||||
Widgets: PageWidgets{
|
||||
LeftSidebar: template.HTML("lalala"),
|
||||
},
|
||||
|
|
|
@ -53,6 +53,7 @@ type User struct {
|
|||
Score int
|
||||
Liked int
|
||||
LastIP string // ! This part of the UserCache data might fall out of date
|
||||
LastAgent string // ! Temporary hack, don't use
|
||||
TempGroup int
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,10 @@ DisableLiveTopicList - This switch allows you to disable the live topic list.
|
|||
|
||||
DisableJSAntispam - This switch lets you disable the JS anti-spam feature. It may be useful if you primarily get users who for one reason or another have decided to disable JavaScript.
|
||||
|
||||
DisableServerPush - This switch lets you disable the HTTP/2 server push feature.
|
||||
|
||||
EnableCDNPush - This switch lets you enable the HTTP/2 CDN Server Push feature. This operates by sending a Link header on every request and may also work with reverse-proxies like Nginx for doing HTTP/2 server pushes.
|
||||
|
||||
NoAvatar - The default avatar to use for users when they don't have their own. The default for this may change in the near future to better utilise HTTP/2. Example: https://api.adorable.io/avatars/{width}/{id}.png
|
||||
|
||||
ItemsPerPage - The number of posts, topics, etc. you want on each page.
|
||||
|
|
|
@ -824,6 +824,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Add a setting to disable this?
|
||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
||||
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
|
||||
var agent string
|
||||
if ua == "" {
|
||||
counters.AgentViewCounter.Bump(26)
|
||||
if common.Dev.DebugMode {
|
||||
|
@ -878,7 +879,6 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// Iterate over this in reverse as the real UA tends to be on the right side
|
||||
var agent string
|
||||
for i := len(items) - 1; i >= 0; i-- {
|
||||
fAgent, ok := markToAgent[items[i]]
|
||||
if ok {
|
||||
|
@ -974,6 +974,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
user.LastAgent = agent
|
||||
if common.Dev.SuperDebug {
|
||||
r.requestLogger.Print(
|
||||
"after PreRoute\n" +
|
||||
|
|
|
@ -603,6 +603,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
// TODO: Add a setting to disable this?
|
||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
||||
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
|
||||
var agent string
|
||||
if ua == "" {
|
||||
counters.AgentViewCounter.Bump({{.AllAgentMap.blank}})
|
||||
if common.Dev.DebugMode {
|
||||
|
@ -657,7 +658,6 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
// Iterate over this in reverse as the real UA tends to be on the right side
|
||||
var agent string
|
||||
for i := len(items) - 1; i >= 0; i-- {
|
||||
fAgent, ok := markToAgent[items[i]]
|
||||
if ok {
|
||||
|
@ -753,6 +753,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
user.LastAgent = agent
|
||||
if common.Dev.SuperDebug {
|
||||
r.requestLogger.Print(
|
||||
"after PreRoute\n" +
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package routes
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -20,6 +21,60 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
|
|||
return halves[0], tid, err
|
||||
}
|
||||
|
||||
func doPush(w http.ResponseWriter, header *common.Header) {
|
||||
//fmt.Println("in doPush")
|
||||
if common.Config.EnableCDNPush {
|
||||
// TODO: Faster string building...
|
||||
var sbuf string
|
||||
var push = func(in []string) {
|
||||
for _, path := range in {
|
||||
sbuf += "</static/" + path + ">; rel=preload; as=script,"
|
||||
}
|
||||
}
|
||||
push(header.Scripts)
|
||||
//push(header.PreScriptsAsync)
|
||||
push(header.ScriptsAsync)
|
||||
|
||||
if len(header.Stylesheets) > 0 {
|
||||
for _, path := range header.Stylesheets {
|
||||
sbuf += "</static/" + path + ">; rel=preload; as=style,"
|
||||
}
|
||||
}
|
||||
// TODO: Push avatars?
|
||||
|
||||
if len(sbuf) > 0 {
|
||||
sbuf = sbuf[:len(sbuf)-1]
|
||||
w.Header().Set("Link", sbuf)
|
||||
}
|
||||
} else if !common.Config.DisableServerPush {
|
||||
//fmt.Println("push enabled")
|
||||
gzw, ok := w.(common.GzipResponseWriter)
|
||||
if ok {
|
||||
w = gzw.ResponseWriter
|
||||
}
|
||||
pusher, ok := w.(http.Pusher)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
//fmt.Println("has pusher")
|
||||
|
||||
var push = func(in []string) {
|
||||
for _, path := range in {
|
||||
//fmt.Println("pushing /static/" + path)
|
||||
err := pusher.Push("/static/"+path, nil)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
push(header.Scripts)
|
||||
//push(header.PreScriptsAsync)
|
||||
push(header.ScriptsAsync)
|
||||
push(header.Stylesheets)
|
||||
// TODO: Push avatars?
|
||||
}
|
||||
}
|
||||
|
||||
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *common.Header, pi interface{}) common.RouteError {
|
||||
if header.CurrentUser.Loggedin {
|
||||
header.MetaDesc = ""
|
||||
|
@ -32,6 +87,14 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
|
|||
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com;upgrade-insecure-requests")
|
||||
}
|
||||
header.AddScript("global.js")
|
||||
|
||||
// Server pushes can backfire on certain browsers, so we want to make sure it's only triggered for ones where it'll help
|
||||
lastAgent := header.CurrentUser.LastAgent
|
||||
//fmt.Println("lastAgent:", lastAgent)
|
||||
if lastAgent == "chrome" || lastAgent == "firefox" {
|
||||
doPush(w, header)
|
||||
}
|
||||
|
||||
if header.CurrentUser.IsAdmin {
|
||||
header.Elapsed1 = time.Since(header.StartedAt).String()
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
<head>
|
||||
<title>{{.Title}} | {{.Header.Site.Name}}</title>
|
||||
{{range .Header.Stylesheets}}
|
||||
<link href="/static/{{.Name}}{{if .Hash}}?h={{.Hash}}{{end}}" rel="stylesheet" type="text/css">{{end}}
|
||||
<link href="/static/{{.}}" rel="stylesheet" type="text/css">{{end}}
|
||||
{{range .Header.PreScriptsAsync}}
|
||||
<script async type="text/javascript" src="/static/{{.Name}}{{if .Hash}}?h={{.Hash}}{{end}}"></script>{{end}}
|
||||
<script async type="text/javascript" src="/static/{{.}}"></script>{{end}}
|
||||
<meta property="x-loggedin" content="{{.CurrentUser.Loggedin}}" />
|
||||
<script type="text/javascript" src="/static/init.js"></script>
|
||||
{{range .Header.ScriptsAsync}}
|
||||
<script async type="text/javascript" src="/static/{{.Name}}{{if .Hash}}?h={{.Hash}}{{end}}"></script>{{end}}
|
||||
<script async type="text/javascript" src="/static/{{.}}"></script>{{end}}
|
||||
<script type="text/javascript" src="/static/jquery-3.1.1.min.js"></script>
|
||||
{{range .Header.Scripts}}
|
||||
<script type="text/javascript" src="/static/{{.Name}}{{if .Hash}}?h={{.Hash}}{{end}}"></script>{{end}}
|
||||
<script type="text/javascript" src="/static/{{.}}"></script>{{end}}
|
||||
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
|
||||
{{if .Header.MetaDesc}}<meta name="description" content="{{.Header.MetaDesc}}" />{{end}}
|
||||
{{/** TODO: Have page / forum / topic level tags and descriptions below as-well **/}}
|
||||
|
|
Loading…
Reference in New Issue