Eliminate zone and prescript allocs in userCheck2().

This commit is contained in:
Azareal 2021-05-10 17:53:52 +10:00
parent 97f411e02e
commit f54203d54f
1 changed files with 57 additions and 38 deletions

View File

@ -24,7 +24,7 @@ var PreRoute func(http.ResponseWriter, *http.Request) (User, bool) = preRoute
var PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*Header, PanelStats, RouteError) = panelUserCheck var PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*Header, PanelStats, RouteError) = panelUserCheck
var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderLite, RouteError) = simplePanelUserCheck var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderLite, RouteError) = simplePanelUserCheck
var SimpleForumUserCheck func(w http.ResponseWriter, r *http.Request, u *User, fid int) (headerLite *HeaderLite, err RouteError) = simpleForumUserCheck var SimpleForumUserCheck func(w http.ResponseWriter, r *http.Request, u *User, fid int) (headerLite *HeaderLite, err RouteError) = simpleForumUserCheck
var ForumUserCheck func(header *Header, w http.ResponseWriter, r *http.Request, u *User, fid int) (err RouteError) = forumUserCheck var ForumUserCheck func(h *Header, w http.ResponseWriter, r *http.Request, u *User, fid int) (err RouteError) = forumUserCheck
var SimpleUserCheck func(w http.ResponseWriter, r *http.Request, u *User) (headerLite *HeaderLite, err RouteError) = simpleUserCheck var SimpleUserCheck func(w http.ResponseWriter, r *http.Request, u *User) (headerLite *HeaderLite, err RouteError) = simpleUserCheck
var UserCheck func(w http.ResponseWriter, r *http.Request, u *User) (h *Header, err RouteError) = userCheck var UserCheck func(w http.ResponseWriter, r *http.Request, u *User) (h *Header, err RouteError) = userCheck
var UserCheckNano func(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, err RouteError) = userCheck2 var UserCheckNano func(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, err RouteError) = userCheck2
@ -222,7 +222,7 @@ func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h
Theme: theme, Theme: theme,
CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function CurrentUser: u, // ! Some things rely on this being a pointer downstream from this function
Hooks: GetHookTable(), Hooks: GetHookTable(),
Zone: "frontend", Zone: ucstrs[0],
Writer: w, Writer: w,
IsoCode: phrases.GetLangPack().IsoCode, IsoCode: phrases.GetLangPack().IsoCode,
StartedAt: nano, StartedAt: nano,
@ -280,31 +280,50 @@ func PrepResources(u *User, h *Header, theme *Theme) {
} }
} }
addPreScript := func(name string) { addPreScript := func(name string, i int) {
// TODO: Optimise this by removing a superfluous string alloc // TODO: Optimise this by removing a superfluous string alloc
var tname string var tname string
if theme.OverridenMap != nil { if theme.OverridenMap != nil {
//fmt.Printf("name %+v\n", name) //fmt.Printf("name %+v\n", name)
//fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap) //fmt.Printf("theme.OverridenMap %+v\n", theme.OverridenMap)
_, ok := theme.OverridenMap[name] if _, ok := theme.OverridenMap[name]; ok {
if ok {
tname = "_" + theme.Name tname = "_" + theme.Name
} }
//fmt.Printf("tname %+v\n", tname)
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
return
} }
//fmt.Printf("tname %+v\n", tname) //fmt.Printf("tname %+v\n", tname)
h.AddPreScriptAsync("tmpl_" + name + tname + ".js") h.AddPreScriptAsync(ucstrs[i])
} }
addPreScript("topics_topic") addPreScript("topics_topic", 1)
addPreScript("paginator") addPreScript("paginator", 2)
addPreScript("alert") addPreScript("alert", 3)
addPreScript("notice") addPreScript("notice", 4)
if u.Loggedin { if u.Loggedin {
addPreScript("topic_c_edit_post") addPreScript("topic_c_edit_post", 5)
addPreScript("topic_c_attach_item") addPreScript("topic_c_attach_item", 6)
addPreScript("topic_c_poll_input") addPreScript("topic_c_poll_input", 7)
} }
} }
func pstr(name string) string {
return "tmpl_" + name + ".js"
}
var ucstrs = [...]string{
"frontend",
pstr("topics_topic"),
pstr("paginator"),
pstr("alert"),
pstr("notice"),
pstr("topic_c_edit_post"),
pstr("topic_c_attach_item"),
pstr("topic_c_poll_input"),
}
func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) { func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
userptr, halt := Auth.SessionCheck(w, r) userptr, halt := Auth.SessionCheck(w, r)
if halt { if halt {
@ -324,7 +343,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
// TODO: Better take proxies into consideration // TODO: Better take proxies into consideration
host, _, err := net.SplitHostPort(r.RemoteAddr) host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil { if err != nil {
PreError("Bad IP", w, r) _ = PreError("Bad IP", w, r)
return *usercpy, false return *usercpy, false
} }
@ -343,7 +362,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
mon := time.Now().Month() mon := time.Now().Month()
err = usercpy.UpdateIP(strconv.Itoa(int(mon)) + "-" + host) err = usercpy.UpdateIP(strconv.Itoa(int(mon)) + "-" + host)
if err != nil { if err != nil {
InternalError(err, w, r) _ = InternalError(err, w, r)
return *usercpy, false return *usercpy, false
} }
} }
@ -352,7 +371,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
return *usercpy, true return *usercpy, true
} }
func UploadAvatar(w http.ResponseWriter, r *http.Request, user *User, tuid int) (ext string, ferr RouteError) { func UploadAvatar(w http.ResponseWriter, r *http.Request, u *User, tuid int) (ext string, ferr RouteError) {
// We don't want multiple files // We don't want multiple files
// TODO: Are we doing this correctly? // TODO: Are we doing this correctly?
filenameMap := make(map[string]bool) filenameMap := make(map[string]bool)
@ -365,7 +384,7 @@ func UploadAvatar(w http.ResponseWriter, r *http.Request, user *User, tuid int)
} }
} }
if len(filenameMap) > 1 { if len(filenameMap) > 1 {
return "", LocalError("You may only upload one avatar", w, r, user) return "", LocalError("You may only upload one avatar", w, r, u)
} }
for _, fheaders := range r.MultipartForm.File { for _, fheaders := range r.MultipartForm.File {
@ -375,67 +394,67 @@ func UploadAvatar(w http.ResponseWriter, r *http.Request, user *User, tuid int)
} }
inFile, err := hdr.Open() inFile, err := hdr.Open()
if err != nil { if err != nil {
return "", LocalError("Upload failed", w, r, user) return "", LocalError("Upload failed", w, r, u)
} }
defer inFile.Close() defer inFile.Close()
if ext == "" { if ext == "" {
extarr := strings.Split(hdr.Filename, ".") extarr := strings.Split(hdr.Filename, ".")
if len(extarr) < 2 { if len(extarr) < 2 {
return "", LocalError("Bad file", w, r, user) return "", LocalError("Bad file", w, r, u)
} }
ext = extarr[len(extarr)-1] ext = extarr[len(extarr)-1]
// TODO: Can we do this without a regex? // TODO: Can we do this without a regex?
reg, err := regexp.Compile("[^A-Za-z0-9]+") reg, err := regexp.Compile("[^A-Za-z0-9]+")
if err != nil { if err != nil {
return "", LocalError("Bad file extension", w, r, user) return "", LocalError("Bad file extension", w, r, u)
} }
ext = reg.ReplaceAllString(ext, "") ext = reg.ReplaceAllString(ext, "")
ext = strings.ToLower(ext) ext = strings.ToLower(ext)
if !ImageFileExts.Contains(ext) { if !ImageFileExts.Contains(ext) {
return "", LocalError("You can only use an image for your avatar", w, r, user) return "", LocalError("You can only use an image for your avatar", w, r, u)
} }
} }
// TODO: Centralise this string, so we don't have to change it in two different places when it changes // TODO: Centralise this string, so we don't have to change it in two different places when it changes
outFile, err := os.Create("./uploads/avatar_" + strconv.Itoa(tuid) + "." + ext) outFile, err := os.Create("./uploads/avatar_" + strconv.Itoa(tuid) + "." + ext)
if err != nil { if err != nil {
return "", LocalError("Upload failed [File Creation Failed]", w, r, user) return "", LocalError("Upload failed [File Creation Failed]", w, r, u)
} }
defer outFile.Close() defer outFile.Close()
_, err = io.Copy(outFile, inFile) _, err = io.Copy(outFile, inFile)
if err != nil { if err != nil {
return "", LocalError("Upload failed [Copy Failed]", w, r, user) return "", LocalError("Upload failed [Copy Failed]", w, r, u)
} }
} }
} }
if ext == "" { if ext == "" {
return "", LocalError("No file", w, r, user) return "", LocalError("No file", w, r, u)
} }
return ext, nil return ext, nil
} }
func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, user *User) RouteError { func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, u *User) RouteError {
err := user.ChangeAvatar(path) e := u.ChangeAvatar(path)
if err != nil { if e != nil {
return InternalError(err, w, r) return InternalError(e, w, r)
} }
// Clean up the old avatar data, so we don't end up with too many dead files in /uploads/ // Clean up the old avatar data, so we don't end up with too many dead files in /uploads/
if len(user.RawAvatar) > 2 { if len(u.RawAvatar) > 2 {
if user.RawAvatar[0] == '.' && user.RawAvatar[1] == '.' { if u.RawAvatar[0] == '.' && u.RawAvatar[1] == '.' {
err := os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "_tmp" + user.RawAvatar[1:]) e := os.Remove("./uploads/avatar_" + strconv.Itoa(u.ID) + "_tmp" + u.RawAvatar[1:])
if err != nil && !os.IsNotExist(err) { if e != nil && !os.IsNotExist(e) {
LogWarning(err) LogWarning(e)
return LocalError("Something went wrong", w, r, user) return LocalError("Something went wrong", w, r, u)
} }
err = os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "_w48" + user.RawAvatar[1:]) e = os.Remove("./uploads/avatar_" + strconv.Itoa(u.ID) + "_w48" + u.RawAvatar[1:])
if err != nil && !os.IsNotExist(err) { if e != nil && !os.IsNotExist(e) {
LogWarning(err) LogWarning(e)
return LocalError("Something went wrong", w, r, user) return LocalError("Something went wrong", w, r, u)
} }
} }
} }