add actionSuccess function to reduce boilerplate
skip doPush if there is nothing to push optimise cdnpush string building use string builder for server push strings
This commit is contained in:
parent
4eaf0c472a
commit
77669d42a5
|
@ -24,52 +24,64 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
|
||||||
return halves[0], tid, err
|
return halves[0], tid, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const slen1 = len("</s/>;rel=preload;as=script,")
|
const slen1 = len("</s/>;rel=preload;as=script,") + 6
|
||||||
const slen2 = len("</s/>;rel=preload;as=style,")
|
const slen2 = len("</s/>;rel=preload;as=style,") + 7
|
||||||
|
|
||||||
var pushCdnPool = sync.Pool{}
|
var pushStrPool = sync.Pool{}
|
||||||
|
|
||||||
func doPush(w http.ResponseWriter, header *c.Header) {
|
func doPush(w http.ResponseWriter, h *c.Header) {
|
||||||
//fmt.Println("in doPush")
|
//fmt.Println("in doPush")
|
||||||
|
if len(h.Scripts) == 0 && len(h.ScriptsAsync) == 0 && len(h.Stylesheets) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
if c.Config.EnableCDNPush {
|
if c.Config.EnableCDNPush {
|
||||||
var sb *strings.Builder
|
var sb *strings.Builder = &strings.Builder{}
|
||||||
ii := pushCdnPool.Get()
|
/*ii := pushStrPool.Get()
|
||||||
if ii == nil {
|
if ii == nil {
|
||||||
sb = &strings.Builder{}
|
sb = &strings.Builder{}
|
||||||
} else {
|
} else {
|
||||||
sb = ii.(*strings.Builder)
|
sb = ii.(*strings.Builder)
|
||||||
sb.Reset()
|
sb.Reset()
|
||||||
}
|
}*/
|
||||||
|
sb.Grow((slen1 * (len(h.Scripts) + len(h.ScriptsAsync))) + ((slen2 + 7) * len(h.Stylesheets)))
|
||||||
push := func(in []string) {
|
push := func(in []string) {
|
||||||
sb.Grow((slen1 + 6) * len(in))
|
for i, path := range in {
|
||||||
for _, path := range in {
|
if i != 0 {
|
||||||
sb.WriteString("</s/")
|
sb.WriteString(",</s/")
|
||||||
|
} else {
|
||||||
|
sb.WriteString("</s/")
|
||||||
|
}
|
||||||
sb.WriteString(path)
|
sb.WriteString(path)
|
||||||
sb.WriteString(">;rel=preload;as=script,")
|
sb.WriteString(">;rel=preload;as=script")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(header.Scripts)
|
push(h.Scripts)
|
||||||
//push(header.PreScriptsAsync)
|
//push(h.PreScriptsAsync)
|
||||||
push(header.ScriptsAsync)
|
push(h.ScriptsAsync)
|
||||||
|
|
||||||
if len(header.Stylesheets) > 0 {
|
if len(h.Stylesheets) > 0 {
|
||||||
sb.Grow((slen2 + 7) * len(header.Stylesheets))
|
for i, path := range h.Stylesheets {
|
||||||
for _, path := range header.Stylesheets {
|
if i != 0 {
|
||||||
sb.WriteString("</s/")
|
sb.WriteString(",</s/")
|
||||||
|
} else {
|
||||||
|
sb.WriteString("</s/")
|
||||||
|
}
|
||||||
sb.WriteString(path)
|
sb.WriteString(path)
|
||||||
sb.WriteString(">;rel=preload;as=style,")
|
sb.WriteString(">;rel=preload;as=style")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Push avatars?
|
// TODO: Push avatars?
|
||||||
|
|
||||||
if sb.Len() > 0 {
|
if sb.Len() > 0 {
|
||||||
sbuf := sb.String()
|
sbuf := sb.String()
|
||||||
pushCdnPool.Put(sb)
|
w.Header().Set("Link", sbuf)
|
||||||
w.Header().Set("Link", sbuf[:len(sbuf)-1])
|
//pushStrPool.Put(sb)
|
||||||
}
|
}
|
||||||
} else if !c.Config.DisableServerPush {
|
} else if !c.Config.DisableServerPush {
|
||||||
//fmt.Println("push enabled")
|
//fmt.Println("push enabled")
|
||||||
if gzw, ok := w.(c.GzipResponseWriter); ok {
|
/*if bzw, ok := w.(c.BrResponseWriter); ok {
|
||||||
|
w = bzw.ResponseWriter
|
||||||
|
} else */if gzw, ok := w.(c.GzipResponseWriter); ok {
|
||||||
w = gzw.ResponseWriter
|
w = gzw.ResponseWriter
|
||||||
}
|
}
|
||||||
pusher, ok := w.(http.Pusher)
|
pusher, ok := w.(http.Pusher)
|
||||||
|
@ -79,21 +91,33 @@ func doPush(w http.ResponseWriter, header *c.Header) {
|
||||||
//panic("has pusher")
|
//panic("has pusher")
|
||||||
//fmt.Println("has pusher")
|
//fmt.Println("has pusher")
|
||||||
|
|
||||||
|
var sb *strings.Builder = &strings.Builder{}
|
||||||
|
/*ii := pushStrPool.Get()
|
||||||
|
if ii == nil {
|
||||||
|
sb = &strings.Builder{}
|
||||||
|
} else {
|
||||||
|
sb = ii.(*strings.Builder)
|
||||||
|
sb.Reset()
|
||||||
|
}*/
|
||||||
|
sb.Grow(6 * (len(h.Scripts) + len(h.ScriptsAsync) + len(h.Stylesheets)))
|
||||||
push := func(in []string) {
|
push := func(in []string) {
|
||||||
for _, path := range in {
|
for _, path := range in {
|
||||||
//fmt.Println("pushing /s/" + path)
|
//fmt.Println("pushing /s/" + path)
|
||||||
// TODO: Avoid concatenating here
|
sb.WriteString("/s/")
|
||||||
err := pusher.Push("/s/"+path, nil)
|
sb.WriteString(path)
|
||||||
|
err := pusher.Push(sb.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
sb.Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(header.Scripts)
|
push(h.Scripts)
|
||||||
//push(header.PreScriptsAsync)
|
//push(h.PreScriptsAsync)
|
||||||
push(header.ScriptsAsync)
|
push(h.ScriptsAsync)
|
||||||
push(header.Stylesheets)
|
push(h.Stylesheets)
|
||||||
// TODO: Push avatars?
|
// TODO: Push avatars?
|
||||||
|
//pushStrPool.Put(sb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,8 +196,21 @@ func renderTemplate3(tmplName, hookName string, w http.ResponseWriter, r *http.R
|
||||||
if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) {
|
if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
/*defer func() {
|
||||||
|
c.StrSlicePool.Put(h.Scripts)
|
||||||
|
c.StrSlicePool.Put(h.PreScriptsAsync)
|
||||||
|
}()*/
|
||||||
return h.Theme.RunTmpl(tmplName, pi, w)
|
return h.Theme.RunTmpl(tmplName, pi, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
|
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
|
||||||
var RenderTemplate = renderTemplate3
|
var RenderTemplate = renderTemplate3
|
||||||
|
|
||||||
|
func actionSuccess(w http.ResponseWriter, r *http.Request, dest string, js bool) c.RouteError {
|
||||||
|
if !js {
|
||||||
|
http.Redirect(w, r, dest, http.StatusSeeOther)
|
||||||
|
} else {
|
||||||
|
_, _ = w.Write(successJSONBytes)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -131,11 +131,5 @@ func ChangeTheme(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError
|
||||||
|
|
||||||
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
|
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
return actionSuccess(w, r, "/", js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -513,13 +513,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid str
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/topic/"+strconv.Itoa(reply.ParentID), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
|
func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
|
||||||
|
@ -558,7 +552,6 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid s
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Unlike(u.ID)
|
err = reply.Unlike(u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
|
@ -581,11 +574,5 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid s
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/topic/"+strconv.Itoa(reply.ParentID), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,12 +103,6 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sItemID
|
||||||
return c.LocalError("Someone has already reported this!", w, r, user)
|
return c.LocalError("Someone has already reported this!", w, r, user)
|
||||||
}
|
}
|
||||||
counters.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
// TODO: Redirect back to where we came from
|
||||||
if !js {
|
return actionSuccess(w, r, "/", js)
|
||||||
// TODO: Redirect back to where we came from
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -979,13 +979,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/topic/"+strconv.Itoa(tid), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
|
func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
|
@ -993,7 +987,6 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := c.Topics.Get(tid)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js)
|
||||||
|
@ -1016,7 +1009,6 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = topic.Unlike(user.ID)
|
err = topic.Unlike(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
|
@ -1039,11 +1031,5 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/topic/"+strconv.Itoa(tid), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
_, _ = w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue