save bytes in the client templates
rename template file and functions to reduce bandwidth usage replace x-loggedin with theoretically faster x-mem remove redundant check in ua loop move extraData initialisation down to where it's needed
This commit is contained in:
parent
6b7c51a604
commit
a668cd296b
|
@ -7,13 +7,13 @@
|
||||||
/public/EQCSS.js
|
/public/EQCSS.js
|
||||||
/schema/**
|
/schema/**
|
||||||
|
|
||||||
template_list.go
|
tmpl_list.go
|
||||||
template_forum.go
|
tmpl_forum.go
|
||||||
template_forums.go
|
tmpl_forums.go
|
||||||
template_topic.go
|
tmpl_topic.go
|
||||||
template_topic_alt.go
|
tmpl_topic_alt.go
|
||||||
template_topics.go
|
tmpl_topics.go
|
||||||
template_profile.go
|
tmpl_profile.go
|
||||||
|
|
||||||
gen_mysql.go
|
gen_mysql.go
|
||||||
gen_mssql.go
|
gen_mssql.go
|
||||||
|
|
|
@ -30,5 +30,5 @@ RouterGen
|
||||||
Patcher
|
Patcher
|
||||||
Gosora
|
Gosora
|
||||||
Installer
|
Installer
|
||||||
template_*.go
|
tmpl_*.go
|
||||||
template_*.jgo
|
tmpl_*.jgo
|
|
@ -1,7 +1,9 @@
|
||||||
echo "Deleting artifacts from previous builds"
|
echo "Deleting artifacts from previous builds"
|
||||||
rm -f template_*.go
|
rm -f template_*.go
|
||||||
|
rm -f tmpl_*.go
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/template_*
|
||||||
|
rm -f tmpl_client/tmpl_*
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
echo "Building the router generator"
|
echo "Building the router generator"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
echo "Deleting artifacts from previous builds"
|
echo "Deleting artifacts from previous builds"
|
||||||
rm -f template_*.go
|
rm -f template_*.go
|
||||||
|
rm -f tmpl_*.go
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/template_*
|
||||||
|
rm -f tmpl_client/tmpl_*
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
echo "Building the router generator"
|
echo "Building the router generator"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
del "tmpl_client/template_*.go"
|
del "tmpl_client/template_*"
|
||||||
|
del "tmpl_client/tmpl_*"
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
echo Generating the dynamic code
|
echo Generating the dynamic code
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ type CSSData struct {
|
||||||
func (list SFileList) JSTmplInit() error {
|
func (list SFileList) JSTmplInit() error {
|
||||||
DebugLog("Initialising the client side templates")
|
DebugLog("Initialising the client side templates")
|
||||||
return filepath.Walk("./tmpl_client", func(path string, f os.FileInfo, err error) error {
|
return filepath.Walk("./tmpl_client", func(path string, f os.FileInfo, err error) error {
|
||||||
if f.IsDir() || strings.HasSuffix(path, "template_list.go") || strings.HasSuffix(path, "stub.go") {
|
if f.IsDir() || strings.HasSuffix(path, "tmpl_list.go") || strings.HasSuffix(path, "stub.go") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
path = strings.Replace(path, "\\", "/", -1)
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
|
@ -58,7 +58,7 @@ func (list SFileList) JSTmplInit() error {
|
||||||
|
|
||||||
path = strings.TrimPrefix(path, "tmpl_client/")
|
path = strings.TrimPrefix(path, "tmpl_client/")
|
||||||
tmplName := strings.TrimSuffix(path, ".jgo")
|
tmplName := strings.TrimSuffix(path, ".jgo")
|
||||||
shortName := strings.TrimPrefix(tmplName, "template_")
|
shortName := strings.TrimPrefix(tmplName, "tmpl_")
|
||||||
|
|
||||||
replace := func(data []byte, replaceThis, withThis string) []byte {
|
replace := func(data []byte, replaceThis, withThis string) []byte {
|
||||||
return bytes.Replace(data, []byte(replaceThis), []byte(withThis), -1)
|
return bytes.Replace(data, []byte(replaceThis), []byte(withThis), -1)
|
||||||
|
@ -73,9 +73,10 @@ func (list SFileList) JSTmplInit() error {
|
||||||
}
|
}
|
||||||
data = data[startIndex-len([]byte("if(tmplInits===undefined)")):]
|
data = data[startIndex-len([]byte("if(tmplInits===undefined)")):]
|
||||||
rep("// nolint", "")
|
rep("// nolint", "")
|
||||||
|
//rep("func ", "function ")
|
||||||
rep("func ", "function ")
|
rep("func ", "function ")
|
||||||
rep(" error {\n", " {\nlet o = \"\"\n")
|
rep(" error {\n", " {\nlet o=\"\"\n")
|
||||||
funcIndex, hasFunc := skipAllUntilCharsExist(data, 0, []byte("function Template_"))
|
funcIndex, hasFunc := skipAllUntilCharsExist(data, 0, []byte("function Tmpl_"))
|
||||||
if !hasFunc {
|
if !hasFunc {
|
||||||
return errors.New("no template function found")
|
return errors.New("no template function found")
|
||||||
}
|
}
|
||||||
|
@ -193,13 +194,13 @@ func (list SFileList) JSTmplInit() error {
|
||||||
//rep("//var plist = GetTmplPhrasesBytes("+shortName+"_tmpl_phrase_id)", "const "+shortName+"_phrase_arr = tmplPhrases[\""+tmplName+"\"];")
|
//rep("//var plist = GetTmplPhrasesBytes("+shortName+"_tmpl_phrase_id)", "const "+shortName+"_phrase_arr = tmplPhrases[\""+tmplName+"\"];")
|
||||||
rep("//var plist = GetTmplPhrasesBytes("+shortName+"_tmpl_phrase_id)", "const pl=tmplPhrases[\""+tmplName+"\"];")
|
rep("//var plist = GetTmplPhrasesBytes("+shortName+"_tmpl_phrase_id)", "const pl=tmplPhrases[\""+tmplName+"\"];")
|
||||||
rep(shortName+"_phrase_arr", "pl")
|
rep(shortName+"_phrase_arr", "pl")
|
||||||
rep("tmpl_"+shortName+"_vars", "t_vars")
|
rep("tmpl_"+shortName+"_vars", "t_v")
|
||||||
|
|
||||||
rep("var c_v_", "let c_v_")
|
rep("var c_v_", "let c_v_")
|
||||||
rep(`t_vars, ok := tmpl_i.`, `/*`)
|
rep(`t_vars, ok := tmpl_i.`, `/*`)
|
||||||
rep("[]byte(", "")
|
rep("[]byte(", "")
|
||||||
rep("StringToBytes(", "")
|
rep("StringToBytes(", "")
|
||||||
rep("RelativeTime(t_vars.", "t_vars.Relative")
|
rep("RelativeTime(t_v.", "t_v.Relative")
|
||||||
// TODO: Format dates properly on the client side
|
// TODO: Format dates properly on the client side
|
||||||
rep(".Format(\"2006-01-02 15:04:05\"", "")
|
rep(".Format(\"2006-01-02 15:04:05\"", "")
|
||||||
rep(", 10", "")
|
rep(", 10", "")
|
||||||
|
@ -211,7 +212,6 @@ func (list SFileList) JSTmplInit() error {
|
||||||
rep("{;", "{")
|
rep("{;", "{")
|
||||||
rep("};", "}")
|
rep("};", "}")
|
||||||
rep("[;", "[")
|
rep("[;", "[")
|
||||||
rep(";;", ";")
|
|
||||||
rep(",;", ",")
|
rep(",;", ",")
|
||||||
rep("=;", "=")
|
rep("=;", "=")
|
||||||
rep(`,
|
rep(`,
|
||||||
|
@ -220,22 +220,33 @@ func (list SFileList) JSTmplInit() error {
|
||||||
rep(`=
|
rep(`=
|
||||||
}`, "=[]")
|
}`, "=[]")
|
||||||
rep("o += ", "o+=")
|
rep("o += ", "o+=")
|
||||||
|
rep(shortName+"_frags[", "fr[")
|
||||||
|
rep("function Tmpl_"+shortName+"(t_v) {","var Tmpl_"+shortName+"=(t_v)=>{")
|
||||||
|
|
||||||
fragset := tmpl.GetFrag(shortName)
|
fragset := tmpl.GetFrag(shortName)
|
||||||
if fragset != nil {
|
if fragset != nil {
|
||||||
sfrags := []byte("let " + shortName + "_frags=[\n")
|
//sfrags := []byte("let " + shortName + "_frags=[\n")
|
||||||
for _, frags := range fragset {
|
sfrags := []byte("{const fr=[")
|
||||||
|
for i, frags := range fragset {
|
||||||
//sfrags = append(sfrags, []byte(shortName+"_frags.push(`"+string(frags)+"`);\n")...)
|
//sfrags = append(sfrags, []byte(shortName+"_frags.push(`"+string(frags)+"`);\n")...)
|
||||||
sfrags = append(sfrags, []byte("`"+string(frags)+"`,\n")...)
|
//sfrags = append(sfrags, []byte("`"+string(frags)+"`,\n")...)
|
||||||
|
if i == 0 {
|
||||||
|
sfrags = append(sfrags, []byte("`"+string(frags)+"`")...)
|
||||||
|
} else {
|
||||||
|
sfrags = append(sfrags, []byte(",`"+string(frags)+"`")...)
|
||||||
}
|
}
|
||||||
sfrags = append(sfrags, []byte("];\n")...)
|
}
|
||||||
|
//sfrags = append(sfrags, []byte("];\n")...)
|
||||||
|
sfrags = append(sfrags, []byte("];")...)
|
||||||
data = append(sfrags, data...)
|
data = append(sfrags, data...)
|
||||||
}
|
}
|
||||||
rep("\n;", "\n")
|
rep("\n;", "\n")
|
||||||
|
rep(";;", ";")
|
||||||
|
|
||||||
|
data = append(data, '}')
|
||||||
for name, _ := range Themes {
|
for name, _ := range Themes {
|
||||||
if strings.HasSuffix(shortName, "_"+name) {
|
if strings.HasSuffix(shortName, "_"+name) {
|
||||||
data = append(data, "\nvar Template_"+strings.TrimSuffix(shortName, "_"+name)+"=Template_"+shortName+";"...)
|
data = append(data, "var Tmpl_"+strings.TrimSuffix(shortName, "_"+name)+"=Tmpl_"+shortName+";"...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,14 @@ var PreRoute func(http.ResponseWriter, *http.Request) (User, bool) = preRoute
|
||||||
// nolint We need these types so people can tell what they are without scrolling to the bottom of the file
|
// nolint We need these types so people can tell what they are without scrolling to the bottom of the file
|
||||||
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, user *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, user *User, fid int) (err RouteError) = forumUserCheck
|
var ForumUserCheck func(header *Header, w http.ResponseWriter, r *http.Request, u *User, fid int) (err RouteError) = forumUserCheck
|
||||||
var SimpleUserCheck func(w http.ResponseWriter, r *http.Request, user *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, user *User) (header *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, user *User, nano int64) (header *Header, err RouteError) = userCheck2
|
var UserCheckNano func(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, err RouteError) = userCheck2
|
||||||
|
|
||||||
func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (header *HeaderLite, rerr RouteError) {
|
func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, u *User, fid int) (header *HeaderLite, rerr RouteError) {
|
||||||
header, rerr = SimpleUserCheck(w, r, user)
|
header, rerr = SimpleUserCheck(w, r, u)
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return header, rerr
|
return header, rerr
|
||||||
}
|
}
|
||||||
|
@ -39,39 +39,39 @@ func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there a better way of doing the skip AND the success flag on this hook like multiple returns?
|
// Is there a better way of doing the skip AND the success flag on this hook like multiple returns?
|
||||||
skip, rerr := header.Hooks.VhookSkippable("simple_forum_check_pre_perms", w, r, user, &fid, &header)
|
skip, rerr := header.Hooks.VhookSkippable("simple_forum_check_pre_perms", w, r, u, &fid, &header)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return header, rerr
|
return header, rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
fperms, err := FPStore.Get(fid, user.Group)
|
fperms, err := FPStore.Get(fid, u.Group)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
fperms = BlankForumPerms()
|
fperms = BlankForumPerms()
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return header, InternalError(err, w, r)
|
return header, InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
cascadeForumPerms(fperms, user)
|
cascadeForumPerms(fperms, u)
|
||||||
return header, nil
|
return header, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func forumUserCheck(header *Header, w http.ResponseWriter, r *http.Request, user *User, fid int) (rerr RouteError) {
|
func forumUserCheck(h *Header, w http.ResponseWriter, r *http.Request, u *User, fid int) (rerr RouteError) {
|
||||||
if !Forums.Exists(fid) {
|
if !Forums.Exists(fid) {
|
||||||
return NotFound(w, r, header)
|
return NotFound(w, r, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, rerr := header.Hooks.VhookSkippable("forum_check_pre_perms", w, r, user, &fid, &header)
|
skip, rerr := h.Hooks.VhookSkippable("forum_check_pre_perms", w, r, u, &fid, &h)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
fperms, err := FPStore.Get(fid, user.Group)
|
fperms, err := FPStore.Get(fid, u.Group)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
fperms = BlankForumPerms()
|
fperms = BlankForumPerms()
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return InternalError(err, w, r)
|
return InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
cascadeForumPerms(fperms, user)
|
cascadeForumPerms(fperms, u)
|
||||||
header.CurrentUser = user // TODO: Use a pointer instead for CurrentUser, so we don't have to do this
|
h.CurrentUser = u // TODO: Use a pointer instead for CurrentUser, so we don't have to do this
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,14 +100,14 @@ func cascadeForumPerms(fp *ForumPerms, u *User) {
|
||||||
|
|
||||||
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
|
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
|
||||||
// TODO: Do a panel specific theme?
|
// TODO: Do a panel specific theme?
|
||||||
func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (h *Header, stats PanelStats, rerr RouteError) {
|
func panelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, stats PanelStats, rerr RouteError) {
|
||||||
theme := GetThemeByReq(r)
|
theme := GetThemeByReq(r)
|
||||||
h = &Header{
|
h = &Header{
|
||||||
Site: Site,
|
Site: Site,
|
||||||
Settings: SettingBox.Load().(SettingMap),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: Themes,
|
Themes: Themes,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
CurrentUser: user,
|
CurrentUser: u,
|
||||||
Hooks: GetHookTable(),
|
Hooks: GetHookTable(),
|
||||||
Zone: "panel",
|
Zone: "panel",
|
||||||
Writer: w,
|
Writer: w,
|
||||||
|
@ -164,7 +164,7 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (h *Head
|
||||||
tname = "_" + theme.Name
|
tname = "_" + theme.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.AddPreScriptAsync("template_" + name + tname + ".js")
|
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
|
||||||
}
|
}
|
||||||
addPreScript("alert")
|
addPreScript("alert")
|
||||||
addPreScript("notice")
|
addPreScript("notice")
|
||||||
|
@ -172,12 +172,12 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (h *Head
|
||||||
return h, stats, nil
|
return h, stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func simplePanelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, rerr RouteError) {
|
func simplePanelUserCheck(w http.ResponseWriter, r *http.Request, u *User) (lite *HeaderLite, rerr RouteError) {
|
||||||
return SimpleUserCheck(w, r, user)
|
return SimpleUserCheck(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleUserCheck is back from the grave, yay :D
|
// SimpleUserCheck is back from the grave, yay :D
|
||||||
func simpleUserCheck(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, rerr RouteError) {
|
func simpleUserCheck(w http.ResponseWriter, r *http.Request, u *User) (lite *HeaderLite, rerr RouteError) {
|
||||||
return &HeaderLite{
|
return &HeaderLite{
|
||||||
Site: Site,
|
Site: Site,
|
||||||
Settings: SettingBox.Load().(SettingMap),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
|
@ -201,20 +201,20 @@ func GetThemeByReq(r *http.Request) *Theme {
|
||||||
return theme
|
return theme
|
||||||
}
|
}
|
||||||
|
|
||||||
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
|
func userCheck(w http.ResponseWriter, r *http.Request, u *User) (h *Header, rerr RouteError) {
|
||||||
return userCheck2(w, r, user, uutils.Nanotime())
|
return userCheck2(w, r, u, uutils.Nanotime())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
||||||
// ! Be careful about firing errors off here as CustomError uses this
|
// ! Be careful about firing errors off here as CustomError uses this
|
||||||
func userCheck2(w http.ResponseWriter, r *http.Request, user *User, nano int64) (h *Header, rerr RouteError) {
|
func userCheck2(w http.ResponseWriter, r *http.Request, u *User, nano int64) (h *Header, rerr RouteError) {
|
||||||
theme := GetThemeByReq(r)
|
theme := GetThemeByReq(r)
|
||||||
h = &Header{
|
h = &Header{
|
||||||
Site: Site,
|
Site: Site,
|
||||||
Settings: SettingBox.Load().(SettingMap),
|
Settings: SettingBox.Load().(SettingMap),
|
||||||
Themes: Themes,
|
Themes: Themes,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
CurrentUser: user, // ! 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: "frontend",
|
||||||
Writer: w,
|
Writer: w,
|
||||||
|
@ -222,24 +222,24 @@ func userCheck2(w http.ResponseWriter, r *http.Request, user *User, nano int64)
|
||||||
StartedAt: nano,
|
StartedAt: nano,
|
||||||
}
|
}
|
||||||
// TODO: Optimise this by avoiding accessing a map string index
|
// TODO: Optimise this by avoiding accessing a map string index
|
||||||
if !user.Loggedin {
|
if !u.Loggedin {
|
||||||
h.GoogSiteVerify = h.Settings["google_site_verify"].(string)
|
h.GoogSiteVerify = h.Settings["google_site_verify"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.IsBanned {
|
if u.IsBanned {
|
||||||
h.AddNotice("account_banned")
|
h.AddNotice("account_banned")
|
||||||
}
|
}
|
||||||
if user.Loggedin && !user.Active {
|
if u.Loggedin && !u.Active {
|
||||||
h.AddNotice("account_inactive")
|
h.AddNotice("account_inactive")
|
||||||
}
|
}
|
||||||
|
|
||||||
// An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway
|
// An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway
|
||||||
// ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well
|
// ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well
|
||||||
//if user.IsAdmin {
|
//if u.IsAdmin {
|
||||||
//h.StartedAt = time.Now()
|
//h.StartedAt = time.Now()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//PrepResources(user,h,theme)
|
//PrepResources(u,h,theme)
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ func PrepResources(u *User, h *Header, theme *Theme) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fmt.Printf("tname %+v\n", tname)
|
//fmt.Printf("tname %+v\n", tname)
|
||||||
h.AddPreScriptAsync("template_" + name + tname + ".js")
|
h.AddPreScriptAsync("tmpl_" + name + tname + ".js")
|
||||||
}
|
}
|
||||||
addPreScript("topics_topic")
|
addPreScript("topics_topic")
|
||||||
addPreScript("paginator")
|
addPreScript("paginator")
|
||||||
|
@ -432,63 +432,63 @@ func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, user *Use
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuperAdminOnly makes sure that only super admin can access certain critical panel routes
|
// SuperAdminOnly makes sure that only super admin can access certain critical panel routes
|
||||||
func SuperAdminOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func SuperAdminOnly(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if !user.IsSuperAdmin {
|
if !u.IsSuperAdmin {
|
||||||
return NoPermissions(w, r, user)
|
return NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminOnly makes sure that only admins can access certain panel routes
|
// AdminOnly makes sure that only admins can access certain panel routes
|
||||||
func AdminOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func AdminOnly(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if !user.IsAdmin {
|
if !u.IsAdmin {
|
||||||
return NoPermissions(w, r, user)
|
return NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuperModeOnly makes sure that only super mods or higher can access the panel routes
|
// SuperModeOnly makes sure that only super mods or higher can access the panel routes
|
||||||
func SuperModOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func SuperModOnly(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if !user.IsSuperMod {
|
if !u.IsSuperMod {
|
||||||
return NoPermissions(w, r, user)
|
return NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemberOnly makes sure that only logged in users can access this route
|
// MemberOnly makes sure that only logged in users can access this route
|
||||||
func MemberOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func MemberOnly(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if !user.Loggedin {
|
if !u.Loggedin {
|
||||||
return LoginRequired(w, r, user)
|
return LoginRequired(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoBanned stops any banned users from accessing this route
|
// NoBanned stops any banned users from accessing this route
|
||||||
func NoBanned(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func NoBanned(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if user.IsBanned {
|
if u.IsBanned {
|
||||||
return Banned(w, r, user)
|
return Banned(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseForm(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func ParseForm(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if err := r.ParseForm(); err != nil {
|
if e := r.ParseForm(); e != nil {
|
||||||
return LocalError("Bad Form", w, r, user)
|
return LocalError("Bad Form", w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NoSessionMismatch(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func NoSessionMismatch(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
if err := r.ParseForm(); err != nil {
|
if e := r.ParseForm(); e != nil {
|
||||||
return LocalError("Bad Form", w, r, user)
|
return LocalError("Bad Form", w, r, u)
|
||||||
}
|
}
|
||||||
// TODO: Try to eliminate some of these allocations
|
// TODO: Try to eliminate some of these allocations
|
||||||
sess := []byte(user.Session)
|
sess := []byte(u.Session)
|
||||||
if len(sess) == 0 {
|
if len(sess) == 0 {
|
||||||
return SecurityError(w, r, user)
|
return SecurityError(w, r, u)
|
||||||
}
|
}
|
||||||
if subtle.ConstantTimeCompare([]byte(r.FormValue("session")), sess) != 1 && subtle.ConstantTimeCompare([]byte(r.FormValue("s")), sess) != 1 {
|
if subtle.ConstantTimeCompare([]byte(r.FormValue("session")), sess) != 1 && subtle.ConstantTimeCompare([]byte(r.FormValue("s")), sess) != 1 {
|
||||||
return SecurityError(w, r, user)
|
return SecurityError(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -497,29 +497,29 @@ func ReqIsJson(r *http.Request) bool {
|
||||||
return r.Header.Get("Content-type") == "application/json"
|
return r.Header.Get("Content-type") == "application/json"
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleUploadRoute(w http.ResponseWriter, r *http.Request, user *User, maxFileSize int) RouteError {
|
func HandleUploadRoute(w http.ResponseWriter, r *http.Request, u *User, maxFileSize int) RouteError {
|
||||||
// TODO: Reuse this code more
|
// TODO: Reuse this code more
|
||||||
if r.ContentLength > int64(maxFileSize) {
|
if r.ContentLength > int64(maxFileSize) {
|
||||||
size, unit := ConvertByteUnit(float64(maxFileSize))
|
size, unit := ConvertByteUnit(float64(maxFileSize))
|
||||||
return CustomError("Your upload is too big. Your files need to be smaller than "+strconv.Itoa(int(size))+unit+".", http.StatusExpectationFailed, "Error", w, r, nil, user)
|
return CustomError("Your upload is too big. Your files need to be smaller than "+strconv.Itoa(int(size))+unit+".", http.StatusExpectationFailed, "Error", w, r, nil, u)
|
||||||
}
|
}
|
||||||
r.Body = http.MaxBytesReader(w, r.Body, r.ContentLength)
|
r.Body = http.MaxBytesReader(w, r.Body, r.ContentLength)
|
||||||
|
|
||||||
err := r.ParseMultipartForm(int64(Megabyte))
|
err := r.ParseMultipartForm(int64(Megabyte))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocalError("Bad Form", w, r, user)
|
return LocalError("Bad Form", w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NoUploadSessionMismatch(w http.ResponseWriter, r *http.Request, user *User) RouteError {
|
func NoUploadSessionMismatch(w http.ResponseWriter, r *http.Request, u *User) RouteError {
|
||||||
// TODO: Try to eliminate some of these allocations
|
// TODO: Try to eliminate some of these allocations
|
||||||
sess := []byte(user.Session)
|
sess := []byte(u.Session)
|
||||||
if len(sess) == 0 {
|
if len(sess) == 0 {
|
||||||
return SecurityError(w, r, user)
|
return SecurityError(w, r, u)
|
||||||
}
|
}
|
||||||
if subtle.ConstantTimeCompare([]byte(r.FormValue("session")), sess) != 1 && subtle.ConstantTimeCompare([]byte(r.FormValue("s")), sess) != 1 {
|
if subtle.ConstantTimeCompare([]byte(r.FormValue("session")), sess) != 1 && subtle.ConstantTimeCompare([]byte(r.FormValue("s")), sess) != 1 {
|
||||||
return SecurityError(w, r, user)
|
return SecurityError(w, r, u)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,7 +389,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
if content == "" {
|
if content == "" {
|
||||||
return //log.Fatal("No content body for " + name)
|
return //log.Fatal("No content body for " + name)
|
||||||
}
|
}
|
||||||
err := writeFile("./template_"+name+".go", content)
|
err := writeFile("./tmpl_"+name+".go", content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
||||||
if tname != "" {
|
if tname != "" {
|
||||||
tname = "_" + tname
|
tname = "_" + tname
|
||||||
}
|
}
|
||||||
err := writeFile(dirPrefix+"template_"+name+tname+".jgo", content)
|
err := writeFile(dirPrefix+"tmpl_"+name+tname+".jgo", content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ func writeTemplateList(c *tmpl.CTemplateSet, wg *sync.WaitGroup, prefix string)
|
||||||
log.Print("Writing template list")
|
log.Print("Writing template list")
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
err := writeFile(prefix+"template_list.go", getTemplateList(c, wg, prefix))
|
err := writeFile(prefix+"tmpl_list.go", getTemplateList(c, wg, prefix))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -685,24 +685,24 @@ func writeTemplateList(c *tmpl.CTemplateSet, wg *sync.WaitGroup, prefix string)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func arithToInt64(in interface{}) (out int64) {
|
func arithToInt64(in interface{}) (o int64) {
|
||||||
switch in := in.(type) {
|
switch in := in.(type) {
|
||||||
case int64:
|
case int64:
|
||||||
out = in
|
o = in
|
||||||
case int32:
|
case int32:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
case int:
|
case int:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
case uint32:
|
case uint32:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
case uint16:
|
case uint16:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
case uint8:
|
case uint8:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
case uint:
|
case uint:
|
||||||
out = int64(in)
|
o = int64(in)
|
||||||
}
|
}
|
||||||
return out
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
func arithDuoToInt64(left, right interface{}) (leftInt, rightInt int64) {
|
func arithDuoToInt64(left, right interface{}) (leftInt, rightInt int64) {
|
||||||
|
|
|
@ -221,11 +221,11 @@ import "errors"
|
||||||
if !c.config.SkipInitBlock {
|
if !c.config.SkipInitBlock {
|
||||||
stub += "// nolint\nfunc init() {\n"
|
stub += "// nolint\nfunc init() {\n"
|
||||||
if !c.config.SkipHandles && c.themeName == "" {
|
if !c.config.SkipHandles && c.themeName == "" {
|
||||||
stub += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
|
stub += "\tc.Tmpl_" + fname + "_handle = Tmpl_" + fname + "\n"
|
||||||
stub += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
stub += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
||||||
}
|
}
|
||||||
if !c.config.SkipTmplPtrMap {
|
if !c.config.SkipTmplPtrMap {
|
||||||
stub += "tmpl := Template_" + fname + "\n"
|
stub += "tmpl := Tmpl_" + fname + "\n"
|
||||||
stub += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
stub += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
||||||
stub += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
stub += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
||||||
}
|
}
|
||||||
|
@ -235,15 +235,15 @@ import "errors"
|
||||||
// TODO: Try to remove this redundant interface cast
|
// TODO: Try to remove this redundant interface cast
|
||||||
stub += `
|
stub += `
|
||||||
// nolint
|
// nolint
|
||||||
func Template_` + fname + `(tmpl_i interface{}, w io.Writer) error {
|
func Tmpl_` + fname + `(tmpl_i interface{}, w io.Writer) error {
|
||||||
tmpl_vars, ok := tmpl_i.(` + expects + `)
|
tmpl_vars, ok := tmpl_i.(` + expects + `)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("invalid page struct value")
|
return errors.New("invalid page struct value")
|
||||||
}
|
}
|
||||||
if tmpl_vars.CurrentUser.Loggedin {
|
if tmpl_vars.CurrentUser.Loggedin {
|
||||||
return Template_` + fname + `_member(tmpl_i, w)
|
return Tmpl_` + fname + `_member(tmpl_i, w)
|
||||||
}
|
}
|
||||||
return Template_` + fname + `_guest(tmpl_i, w)
|
return Tmpl_` + fname + `_guest(tmpl_i, w)
|
||||||
}`
|
}`
|
||||||
|
|
||||||
c.fileDir = fileDir
|
c.fileDir = fileDir
|
||||||
|
@ -453,15 +453,20 @@ func (c *CTemplateSet) compile(name, content, expects string, expectsInt interfa
|
||||||
if c.lang == "js" {
|
if c.lang == "js" {
|
||||||
var l string
|
var l string
|
||||||
if len(c.langIndexToName) > 0 {
|
if len(c.langIndexToName) > 0 {
|
||||||
for _, name := range c.langIndexToName {
|
for i, name := range c.langIndexToName {
|
||||||
l += "\t" + `"` + name + `"` + ",\n"
|
//l += `"` + name + `"` + ",\n"
|
||||||
|
if i == 0{
|
||||||
|
l += `"` + name + `"`
|
||||||
|
} else {
|
||||||
|
l += `,"` + name + `"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(l) > 0 {
|
}
|
||||||
|
/*if len(l) > 0 {
|
||||||
l = "\n" + l
|
l = "\n" + l
|
||||||
}
|
}*/
|
||||||
fout += "if(tmplInits===undefined) var tmplInits = {}\n"
|
fout += "if(tmplInits===undefined) var tmplInits={}\n"
|
||||||
fout += "tmplInits[\"template_" + fname + "\"] = [" + l + "]\n"
|
fout += "tmplInits[\"tmpl_" + fname + "\"]=[" + l + "]"
|
||||||
} else if !c.config.SkipInitBlock {
|
} else if !c.config.SkipInitBlock {
|
||||||
if len(c.langIndexToName) > 0 {
|
if len(c.langIndexToName) > 0 {
|
||||||
fout += "var " + fname + "_tmpl_phrase_id int\n\n"
|
fout += "var " + fname + "_tmpl_phrase_id int\n\n"
|
||||||
|
@ -470,12 +475,12 @@ func (c *CTemplateSet) compile(name, content, expects string, expectsInt interfa
|
||||||
fout += "// nolint\nfunc init() {\n"
|
fout += "// nolint\nfunc init() {\n"
|
||||||
|
|
||||||
if !c.config.SkipHandles && c.themeName == "" {
|
if !c.config.SkipHandles && c.themeName == "" {
|
||||||
fout += "\tc.Template_" + fname + "_handle = Template_" + fname + "\n"
|
fout += "\tc.Tmpl_" + fname + "_handle = Tmpl_" + fname + "\n"
|
||||||
fout += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
fout += "\tc.Ctemplates = append(c.Ctemplates,\"" + fname + "\")\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.config.SkipTmplPtrMap {
|
if !c.config.SkipTmplPtrMap {
|
||||||
fout += "tmpl := Template_" + fname + "\n"
|
fout += "tmpl := Tmpl_" + fname + "\n"
|
||||||
fout += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
fout += "\tc.TmplPtrMap[\"" + fname + "\"] = &tmpl\n"
|
||||||
fout += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
fout += "\tc.TmplPtrMap[\"o_" + fname + "\"] = tmpl\n"
|
||||||
}
|
}
|
||||||
|
@ -495,7 +500,7 @@ func (c *CTemplateSet) compile(name, content, expects string, expectsInt interfa
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.lang == "normal" {
|
if c.lang == "normal" {
|
||||||
fout += "// nolint\nfunc Template_" + fname + "(tmpl_i interface{}, w io.Writer) error {\n"
|
fout += "// nolint\nfunc Tmpl_" + fname + "(tmpl_i interface{}, w io.Writer) error {\n"
|
||||||
fout += `tmpl_` + fname + `_vars, ok := tmpl_i.(` + expects + `)
|
fout += `tmpl_` + fname + `_vars, ok := tmpl_i.(` + expects + `)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("invalid page struct value")
|
return errors.New("invalid page struct value")
|
||||||
|
@ -514,8 +519,8 @@ if !ok {
|
||||||
_ = iw
|
_ = iw
|
||||||
`
|
`
|
||||||
} else {
|
} else {
|
||||||
fout += "// nolint\nfunc Template_" + fname + "(tmpl_" + fname + "_vars interface{}, w io.Writer) error {\n"
|
fout += "// nolint\nfunc Tmpl_" + fname + "(tmpl_" + fname + "_vars interface{}, w io.Writer) error {\n"
|
||||||
//fout += "// nolint\nfunc Template_" + fname + "(tmpl_vars interface{}, w io.Writer) error {\n"
|
//fout += "// nolint\nfunc Tmpl_" + fname + "(tmpl_vars interface{}, w io.Writer) error {\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.langIndexToName) > 0 {
|
if len(c.langIndexToName) > 0 {
|
||||||
|
|
|
@ -133,11 +133,11 @@ easyjson -pkg common
|
||||||
|
|
||||||
go get
|
go get
|
||||||
|
|
||||||
rm -f template_*.go
|
rm -f tmpl_*.go
|
||||||
|
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
|
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/tmpl_*.go
|
||||||
|
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"bytes"
|
//"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -1058,12 +1058,6 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
r.requestLogger.Print("before PreRoute")
|
r.requestLogger.Print("before PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraData string
|
|
||||||
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
|
|
||||||
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
|
|
||||||
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if c.Dev.QuicPort != 0 {
|
/*if c.Dev.QuicPort != 0 {
|
||||||
w.Header().Set("Alt-Svc", "quic=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h3-24=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h2=\":443\"; ma=3600")
|
w.Header().Set("Alt-Svc", "quic=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h3-24=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h2=\":443\"; ma=3600")
|
||||||
}*/
|
}*/
|
||||||
|
@ -1093,7 +1087,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
for _, it := range uutils.StringToBytes(ua) {
|
for _, it := range uutils.StringToBytes(ua) {
|
||||||
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
|
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
|
||||||
buffer = append(buffer, it)
|
buffer = append(buffer, it)
|
||||||
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' || (it == ':' && bytes.Equal(buffer,[]byte("http"))) || it == ',' || it == '/' {
|
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' /*|| (it == ':' && bytes.Equal(buffer,[]byte("http")))*/ || it == ',' || it == '/' {
|
||||||
if len(buffer) != 0 {
|
if len(buffer) != 0 {
|
||||||
if len(buffer) > 2 {
|
if len(buffer) > 2 {
|
||||||
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
|
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
|
||||||
|
@ -1120,8 +1114,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// TODO: Test this
|
// TODO: Test this
|
||||||
items = items[:0]
|
items = items[:0]
|
||||||
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA")
|
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA")
|
||||||
r.requestLogger.Print("UA Buffer: ", buffer)
|
r.requestLogger.Print("UA Buf: ", buffer)
|
||||||
r.requestLogger.Print("UA Buffer String: ", string(buffer))
|
r.requestLogger.Print("UA Buf String: ", string(buffer))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,6 +1239,12 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w = gzw
|
w = gzw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var extraData string
|
||||||
|
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
|
||||||
|
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
|
||||||
|
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
||||||
|
}
|
||||||
|
|
||||||
skip, ferr = hTbl.VhookSkippable("router_pre_route", w, req, user, prefix, extraData)
|
skip, ferr = hTbl.VhookSkippable("router_pre_route", w, req, user, prefix, extraData)
|
||||||
if skip || ferr != nil {
|
if skip || ferr != nil {
|
||||||
r.handleError(ferr,w,req,user)
|
r.handleError(ferr,w,req,user)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
echo "Deleting artifacts from previous builds"
|
echo "Deleting artifacts from previous builds"
|
||||||
rm -f template_*.go
|
rm -f template_*.go
|
||||||
|
rm -f tmpl_*.go
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/template_*
|
||||||
|
rm -f tmpl_client/tmpl_*
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
echo "Generating the dynamic code"
|
echo "Generating the dynamic code"
|
||||||
|
|
|
@ -18,7 +18,7 @@ var forumToMoveTo = 0;
|
||||||
function pushNotice(msg) {
|
function pushNotice(msg) {
|
||||||
let aBox = document.getElementsByClassName("alertbox")[0];
|
let aBox = document.getElementsByClassName("alertbox")[0];
|
||||||
let div = document.createElement('div');
|
let div = document.createElement('div');
|
||||||
div.innerHTML = Template_notice(msg).trim();
|
div.innerHTML = Tmpl_notice(msg).trim();
|
||||||
aBox.appendChild(div);
|
aBox.appendChild(div);
|
||||||
runInitHook("after_notice");
|
runInitHook("after_notice");
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ function pushNotice(msg) {
|
||||||
// TODO: Write a friendlier error handler which uses a .notice or something, we could have a specialised one for alerts
|
// TODO: Write a friendlier error handler which uses a .notice or something, we could have a specialised one for alerts
|
||||||
function ajaxError(xhr,status,errstr) {
|
function ajaxError(xhr,status,errstr) {
|
||||||
console.log("The AJAX request failed");
|
console.log("The AJAX request failed");
|
||||||
console.log("xhr", xhr);
|
console.log("xhr",xhr);
|
||||||
console.log("status", status);
|
console.log("status",status);
|
||||||
console.log("err", errstr);
|
console.log("err",errstr);
|
||||||
if(status=="parsererror") console.log("The server didn't respond with a valid JSON response");
|
if(status=="parsererror") console.log("The server didn't respond with a valid JSON response");
|
||||||
console.trace();
|
console.trace();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ function addAlert(msg, notice=false) {
|
||||||
for(var i = 0; i < msg.sub.length; i++) mmsg = mmsg.replace("\{"+i+"\}", msg.sub[i]);
|
for(var i = 0; i < msg.sub.length; i++) mmsg = mmsg.replace("\{"+i+"\}", msg.sub[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let aItem = Template_alert({
|
let aItem = Tmpl_alert({
|
||||||
ASID: msg.id,
|
ASID: msg.id,
|
||||||
Path: msg.path,
|
Path: msg.path,
|
||||||
Avatar: msg.img || "",
|
Avatar: msg.img || "",
|
||||||
|
@ -291,12 +291,12 @@ function runWebSockets(resume=false) {
|
||||||
console.log("topic in data");
|
console.log("topic in data");
|
||||||
console.log("data",data);
|
console.log("data",data);
|
||||||
let topic = data.Topics[0];
|
let topic = data.Topics[0];
|
||||||
if(topic === undefined){
|
if(topic===undefined){
|
||||||
console.log("empty topic list");
|
console.log("empty topic list");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: Fix the data race where the function hasn't been loaded yet
|
// TODO: Fix the data race where the function hasn't been loaded yet
|
||||||
let renTopic = Template_topics_topic(topic);
|
let renTopic = Tmpl_topics_topic(topic);
|
||||||
$(".topic_row[data-tid='"+topic.ID+"']").addClass("ajax_topic_dupe");
|
$(".topic_row[data-tid='"+topic.ID+"']").addClass("ajax_topic_dupe");
|
||||||
|
|
||||||
let node = $(renTopic);
|
let node = $(renTopic);
|
||||||
|
@ -316,8 +316,7 @@ function runWebSockets(resume=false) {
|
||||||
msgBox.innerText = phraseBox["topic_list"]["topic_list.changed_topics"].replace("%d",moreTopicCount);
|
msgBox.innerText = phraseBox["topic_list"]["topic_list.changed_topics"].replace("%d",moreTopicCount);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("unknown message");
|
console.log("unknown message", data);
|
||||||
console.log(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,10 +352,10 @@ function getExt(name) {
|
||||||
console.log("before notify on alert")
|
console.log("before notify on alert")
|
||||||
// We can only get away with this because template_alert has no phrases, otherwise it too would have to be part of the "dance", I miss Go concurrency :(
|
// We can only get away with this because template_alert has no phrases, otherwise it too would have to be part of the "dance", I miss Go concurrency :(
|
||||||
if(!noAlerts) {
|
if(!noAlerts) {
|
||||||
notifyOnScriptW("template_alert", e => {
|
notifyOnScriptW("tmpl_alert", e => {
|
||||||
if(e!=undefined) console.log("failed alert? why?",e)
|
if(e!=undefined) console.log("failed alert? why?",e)
|
||||||
}, () => {
|
}, () => {
|
||||||
if(!Template_alert) throw("template function not found");
|
if(!Tmpl_alert) throw("template function not found");
|
||||||
addInitHook("after_phrases", () => {
|
addInitHook("after_phrases", () => {
|
||||||
// TODO: The load part of loadAlerts could be done asynchronously while the update of the DOM could be deferred
|
// TODO: The load part of loadAlerts could be done asynchronously while the update of the DOM could be deferred
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
|
@ -381,7 +380,7 @@ function getExt(name) {
|
||||||
|
|
||||||
// TODO: Use these in .filter_item and pass back an item count from the backend to work with here
|
// TODO: Use these in .filter_item and pass back an item count from the backend to work with here
|
||||||
// Ported from common/parser.go
|
// Ported from common/parser.go
|
||||||
function PageOffset(count, page, perPage) {
|
function PageOffset(count,page,perPage) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let lastPage = LastPage(count, perPage)
|
let lastPage = LastPage(count, perPage)
|
||||||
if(page > 1) offset = (perPage * page) - perPage;
|
if(page > 1) offset = (perPage * page) - perPage;
|
||||||
|
@ -394,10 +393,10 @@ function PageOffset(count, page, perPage) {
|
||||||
//if(offset >= (count - 1)) offset = 0;
|
//if(offset >= (count - 1)) offset = 0;
|
||||||
return {Offset:offset, Page:page, LastPage:lastPage};
|
return {Offset:offset, Page:page, LastPage:lastPage};
|
||||||
}
|
}
|
||||||
function LastPage(count, perPage) {
|
function LastPage(count,perPage) {
|
||||||
return (count / perPage) + 1
|
return (count / perPage) + 1
|
||||||
}
|
}
|
||||||
function Paginate(currentPage, lastPage, maxPages) {
|
function Paginate(currentPage,lastPage,maxPages) {
|
||||||
let diff = lastPage - currentPage;
|
let diff = lastPage - currentPage;
|
||||||
let pre = 3;
|
let pre = 3;
|
||||||
if(diff < 3) pre = maxPages - diff;
|
if(diff < 3) pre = maxPages - diff;
|
||||||
|
@ -488,13 +487,13 @@ function mainInit(){
|
||||||
if(page=="") page = 1;
|
if(page=="") page = 1;
|
||||||
|
|
||||||
let pageList = Paginate(page,lastPage,5)
|
let pageList = Paginate(page,lastPage,5)
|
||||||
//$(".pageset").html(Template_paginator({PageList: pageList, Page: page, LastPage: lastPage}));
|
//$(".pageset").html(Tmpl_paginator({PageList: pageList, Page: page, LastPage: lastPage}));
|
||||||
let ok = false;
|
let ok = false;
|
||||||
$(".pageset").each(function(){
|
$(".pageset").each(function(){
|
||||||
this.outerHTML = Template_paginator({PageList: pageList, Page: page, LastPage: lastPage});
|
this.outerHTML = Tmpl_paginator({PageList: pageList, Page: page, LastPage: lastPage});
|
||||||
ok = true;
|
ok = true;
|
||||||
});
|
});
|
||||||
if(!ok) $(Template_paginator({PageList: pageList, Page: page, LastPage: lastPage})).insertAfter("#topic_list");
|
if(!ok) $(Tmpl_paginator({PageList: pageList, Page: page, LastPage: lastPage})).insertAfter("#topic_list");
|
||||||
}
|
}
|
||||||
|
|
||||||
function rebindPaginator() {
|
function rebindPaginator() {
|
||||||
|
@ -521,7 +520,7 @@ function mainInit(){
|
||||||
|
|
||||||
// TODO: Fix the data race where the function hasn't been loaded yet
|
// TODO: Fix the data race where the function hasn't been loaded yet
|
||||||
let out = "";
|
let out = "";
|
||||||
for(let i = 0; i < topics.length;i++) out += Template_topics_topic(topics[i]);
|
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]);
|
||||||
$(".topic_list").html(out);
|
$(".topic_list").html(out);
|
||||||
|
|
||||||
let obj = {Title: document.title, Url: url+q};
|
let obj = {Title: document.title, Url: url+q};
|
||||||
|
@ -530,7 +529,7 @@ function mainInit(){
|
||||||
rebindPaginator();
|
rebindPaginator();
|
||||||
}).catch(ex => {
|
}).catch(ex => {
|
||||||
console.log("Unable to get script '"+url+q+"&js=1"+"'");
|
console.log("Unable to get script '"+url+q+"&js=1"+"'");
|
||||||
console.log("ex", ex);
|
console.log("ex",ex);
|
||||||
console.trace();
|
console.trace();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -557,7 +556,7 @@ function mainInit(){
|
||||||
|
|
||||||
// TODO: Fix the data race where the function hasn't been loaded yet
|
// TODO: Fix the data race where the function hasn't been loaded yet
|
||||||
let out = "";
|
let out = "";
|
||||||
for(let i = 0; i < topics.length;i++) out += Template_topics_topic(topics[i]);
|
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]);
|
||||||
$(".topic_list").html(out);
|
$(".topic_list").html(out);
|
||||||
//$(".topic_list").addClass("single_forum");
|
//$(".topic_list").addClass("single_forum");
|
||||||
|
|
||||||
|
@ -608,7 +607,7 @@ function mainInit(){
|
||||||
|
|
||||||
// TODO: Fix the data race where the function hasn't been loaded yet
|
// TODO: Fix the data race where the function hasn't been loaded yet
|
||||||
let out = "";
|
let out = "";
|
||||||
for(let i = 0; i < topics.length;i++) out += Template_topics_topic(topics[i]);
|
for(let i = 0; i < topics.length;i++) out += Tmpl_topics_topic(topics[i]);
|
||||||
$(".topic_list").html(out);
|
$(".topic_list").html(out);
|
||||||
|
|
||||||
baseTitle = phraseBox["topic_list"]["topic_list.search_head"];
|
baseTitle = phraseBox["topic_list"]["topic_list.search_head"];
|
||||||
|
@ -791,7 +790,7 @@ function mainInit(){
|
||||||
console.log("date", date);
|
console.log("date", date);
|
||||||
let minutes = "0" + date.getMinutes();
|
let minutes = "0" + date.getMinutes();
|
||||||
let formattedTime = date.getHours() + ":" + minutes.substr(-2);
|
let formattedTime = date.getHours() + ":" + minutes.substr(-2);
|
||||||
console.log("formattedTime", formattedTime);
|
console.log("formattedTime",formattedTime);
|
||||||
this.innerText = formattedTime;
|
this.innerText = formattedTime;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -799,7 +798,7 @@ function mainInit(){
|
||||||
// TODO: Localise this
|
// TODO: Localise this
|
||||||
let monthList = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
let monthList = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
||||||
let date = new Date(this.innerText * 1000);
|
let date = new Date(this.innerText * 1000);
|
||||||
console.log("date", date);
|
console.log("date",date);
|
||||||
let day = "0" + date.getDate();
|
let day = "0" + date.getDate();
|
||||||
let formattedTime = monthList[date.getMonth()] + " " + day.substr(-2) + " " + date.getFullYear();
|
let formattedTime = monthList[date.getMonth()] + " " + day.substr(-2) + " " + date.getFullYear();
|
||||||
console.log("formattedTime",formattedTime);
|
console.log("formattedTime",formattedTime);
|
||||||
|
@ -976,7 +975,7 @@ function bindTopic() {
|
||||||
let src = "";
|
let src = "";
|
||||||
if(srcNode!=null) src = srcNode.innerText;
|
if(srcNode!=null) src = srcNode.innerText;
|
||||||
else src = block.innerHTML;
|
else src = block.innerHTML;
|
||||||
block.innerHTML = Template_topic_c_edit_post({
|
block.innerHTML = Tmpl_topic_c_edit_post({
|
||||||
ID: bp.getAttribute("id").slice("post-".length),
|
ID: bp.getAttribute("id").slice("post-".length),
|
||||||
Source: src,
|
Source: src,
|
||||||
Ref: this.closest('a').getAttribute("href")
|
Ref: this.closest('a').getAttribute("href")
|
||||||
|
@ -1014,13 +1013,13 @@ function bindTopic() {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
let src = this.closest(".post_item").getElementsByClassName("edit_source")[0];
|
let src = this.closest(".post_item").getElementsByClassName("edit_source")[0];
|
||||||
let content = document.getElementById("input_content")
|
let content = document.getElementById("input_content")
|
||||||
console.log("content.value", content.value);
|
console.log("content.value",content.value);
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
if(content.value=="") item = "<blockquote>" + src.innerHTML + "</blockquote>"
|
if(content.value=="") item = "<blockquote>" + src.innerHTML + "</blockquote>"
|
||||||
else item = "\r\n<blockquote>" + src.innerHTML + "</blockquote>";
|
else item = "\r\n<blockquote>" + src.innerHTML + "</blockquote>";
|
||||||
content.value = content.value + item;
|
content.value = content.value + item;
|
||||||
console.log("content.value", content.value);
|
console.log("content.value",content.value);
|
||||||
|
|
||||||
// For custom / third party text editors
|
// For custom / third party text editors
|
||||||
quoteItemCallback(src.innerHTML,item);
|
quoteItemCallback(src.innerHTML,item);
|
||||||
|
|
|
@ -185,7 +185,7 @@ function fetchPhrases(plist) {
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
runInitHook("pre_iife");
|
runInitHook("pre_iife");
|
||||||
let loggedIn = document.head.querySelector("[property='x-loggedin']").content=="true";
|
let loggedIn = document.head.querySelector("[property='x-mem']")!=null;
|
||||||
let panel = window.location.pathname.startsWith("/panel/");
|
let panel = window.location.pathname.startsWith("/panel/");
|
||||||
|
|
||||||
let toLoad = 1;
|
let toLoad = 1;
|
||||||
|
@ -200,21 +200,20 @@ function fetchPhrases(plist) {
|
||||||
toLoad += 2;
|
toLoad += 2;
|
||||||
if(loggedIn) {
|
if(loggedIn) {
|
||||||
toLoad += 3;
|
toLoad += 3;
|
||||||
notifyOnScriptW("template_topic_c_edit_post", () => q(!Template_topic_c_edit_post));
|
notifyOnScriptW("tmpl_topic_c_edit_post", () => q(!Tmpl_topic_c_edit_post));
|
||||||
notifyOnScriptW("template_topic_c_attach_item", () => q(!Template_topic_c_attach_item));
|
notifyOnScriptW("tmpl_topic_c_attach_item", () => q(!Tmpl_topic_c_attach_item));
|
||||||
notifyOnScriptW("template_topic_c_poll_input", () => q(!Template_topic_c_poll_input));
|
notifyOnScriptW("tmpl_topic_c_poll_input", () => q(!Tmpl_topic_c_poll_input));
|
||||||
}
|
}
|
||||||
notifyOnScriptW("template_topics_topic", () => q(!Template_topics_topic));
|
notifyOnScriptW("tmpl_topics_topic", () => q(!Tmpl_topics_topic));
|
||||||
notifyOnScriptW("template_paginator", () => q(!Template_paginator));
|
notifyOnScriptW("tmpl_paginator", () => q(!Tmpl_paginator));
|
||||||
}
|
}
|
||||||
notifyOnScriptW("template_notice", () => q(!Template_notice));
|
notifyOnScriptW("tmpl_notice", () => q(!Tmpl_notice));
|
||||||
|
|
||||||
if(loggedIn) {
|
if(loggedIn) {
|
||||||
fetch("/api/me/")
|
fetch("/api/me/")
|
||||||
.then(resp => resp.json())
|
.then(resp => resp.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log("loaded me endpoint data");
|
console.log("loaded me endpoint data",data);
|
||||||
console.log("data",data);
|
|
||||||
me = data;
|
me = data;
|
||||||
runInitHook("pre_init");
|
runInitHook("pre_init");
|
||||||
});
|
});
|
||||||
|
|
|
@ -76,7 +76,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
|
||||||
let c = "";
|
let c = "";
|
||||||
if(isImage) c = " attach_image_holder"
|
if(isImage) c = " attach_image_holder"
|
||||||
fileItem.className = "attach_item attach_item_item" + c;
|
fileItem.className = "attach_item attach_item_item" + c;
|
||||||
fileItem.innerHTML = Template_topic_c_attach_item({
|
fileItem.innerHTML = Tmpl_topic_c_attach_item({
|
||||||
ID: data.elems[hash+"."+ext],
|
ID: data.elems[hash+"."+ext],
|
||||||
ImgSrc: isImage ? e.target.result : "",
|
ImgSrc: isImage ? e.target.result : "",
|
||||||
Path: hash+"."+ext,
|
Path: hash+"."+ext,
|
||||||
|
@ -286,7 +286,7 @@ var imageExts = ["png", "jpg", "jpe","jpeg","jif","jfi","jfif", "svg", "bmp", "g
|
||||||
console.log("dataPollInput",dataPollInput);
|
console.log("dataPollInput",dataPollInput);
|
||||||
if(dataPollInput==undefined) return;
|
if(dataPollInput==undefined) return;
|
||||||
if(dataPollInput!=(pollInputIndex-1)) return;
|
if(dataPollInput!=(pollInputIndex-1)) return;
|
||||||
$(".poll_content_row .formitem").append(Template_topic_c_poll_input({
|
$(".poll_content_row .formitem").append(Tmpl_topic_c_poll_input({
|
||||||
Index: pollInputIndex,
|
Index: pollInputIndex,
|
||||||
Place: phraseBox["topic"]["topic.reply_add_poll_option"].replace("%d",pollInputIndex),
|
Place: phraseBox["topic"]["topic.reply_add_poll_option"].replace("%d",pollInputIndex),
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -416,7 +416,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"bytes"
|
//"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -736,12 +736,6 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
r.requestLogger.Print("before PreRoute")
|
r.requestLogger.Print("before PreRoute")
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraData string
|
|
||||||
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
|
|
||||||
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
|
|
||||||
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if c.Dev.QuicPort != 0 {
|
/*if c.Dev.QuicPort != 0 {
|
||||||
w.Header().Set("Alt-Svc", "quic=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h3-24=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h2=\":443\"; ma=3600")
|
w.Header().Set("Alt-Svc", "quic=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h3-24=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h2=\":443\"; ma=3600")
|
||||||
}*/
|
}*/
|
||||||
|
@ -771,7 +765,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
for _, it := range uutils.StringToBytes(ua) {
|
for _, it := range uutils.StringToBytes(ua) {
|
||||||
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
|
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
|
||||||
buffer = append(buffer, it)
|
buffer = append(buffer, it)
|
||||||
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' || (it == ':' && bytes.Equal(buffer,[]byte("http"))) || it == ',' || it == '/' {
|
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' /*|| (it == ':' && bytes.Equal(buffer,[]byte("http")))*/ || it == ',' || it == '/' {
|
||||||
if len(buffer) != 0 {
|
if len(buffer) != 0 {
|
||||||
if len(buffer) > 2 {
|
if len(buffer) > 2 {
|
||||||
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
|
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
|
||||||
|
@ -798,8 +792,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
// TODO: Test this
|
// TODO: Test this
|
||||||
items = items[:0]
|
items = items[:0]
|
||||||
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA")
|
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA")
|
||||||
r.requestLogger.Print("UA Buffer: ", buffer)
|
r.requestLogger.Print("UA Buf: ", buffer)
|
||||||
r.requestLogger.Print("UA Buffer String: ", string(buffer))
|
r.requestLogger.Print("UA Buf String: ", string(buffer))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -923,6 +917,12 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w = gzw
|
w = gzw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var extraData string
|
||||||
|
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
|
||||||
|
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
|
||||||
|
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
||||||
|
}
|
||||||
|
|
||||||
skip, ferr = hTbl.VhookSkippable("router_pre_route", w, req, user, prefix, extraData)
|
skip, ferr = hTbl.VhookSkippable("router_pre_route", w, req, user, prefix, extraData)
|
||||||
if skip || ferr != nil {
|
if skip || ferr != nil {
|
||||||
r.handleError(ferr,w,req,user)
|
r.handleError(ferr,w,req,user)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
echo "Deleting artifacts from previous builds"
|
echo "Deleting artifacts from previous builds"
|
||||||
rm -f template_*.go
|
rm -f template_*.go
|
||||||
|
rm -f tmpl_*.go
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/template_*
|
||||||
|
rm -f tmpl_client/tmpl_*
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
echo "Generating the dynamic code"
|
echo "Generating the dynamic code"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
echo "Deleting artifacts from previous builds"
|
echo "Deleting artifacts from previous builds"
|
||||||
rm -f template_*.go
|
rm -f template_*.go
|
||||||
|
rm -f tmpl_*.go
|
||||||
rm -f gen_*.go
|
rm -f gen_*.go
|
||||||
rm -f tmpl_client/template_*.go
|
rm -f tmpl_client/template_*
|
||||||
|
rm -f tmpl_client/tmpl_*
|
||||||
rm -f ./Gosora
|
rm -f ./Gosora
|
||||||
|
|
||||||
echo "Generating the dynamic code"
|
echo "Generating the dynamic code"
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
|
6
run.bat
6
run.bat
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ if %errorlevel% neq 0 (
|
||||||
)
|
)
|
||||||
|
|
||||||
echo Building the executable... again
|
echo Building the executable... again
|
||||||
go build -ldflags="-s -w" -o gosora.exe
|
go build -ldflags="-s -w" -gcflags="-d=ssa/check_bce/debug=1" -o gosora.exe
|
||||||
if %errorlevel% neq 0 (
|
if %errorlevel% neq 0 (
|
||||||
pause
|
pause
|
||||||
exit /b %errorlevel%
|
exit /b %errorlevel%
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
rem TODO: Make these deletes a little less noisy
|
rem TODO: Make these deletes a little less noisy
|
||||||
del "template_*.go"
|
del "template_*.go"
|
||||||
|
del "tmpl_*.go"
|
||||||
del "gen_*.go"
|
del "gen_*.go"
|
||||||
cd tmpl_client
|
cd tmpl_client
|
||||||
del "template_*.go"
|
del "template_*"
|
||||||
|
del "tmpl_*"
|
||||||
cd ..
|
cd ..
|
||||||
del "gosora.exe"
|
del "gosora.exe"
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<link href="/s/{{.}}"rel="stylesheet"type="text/css">{{end}}
|
<link href="/s/{{.}}"rel="stylesheet"type="text/css">{{end}}
|
||||||
{{range .Header.PreScriptsAsync}}
|
{{range .Header.PreScriptsAsync}}
|
||||||
<script async src="/s/{{.}}"></script>{{end}}
|
<script async src="/s/{{.}}"></script>{{end}}
|
||||||
<meta property="x-loggedin"content="{{.CurrentUser.Loggedin}}">
|
{{if .CurrentUser.Loggedin}}<meta property="x-mem"content="1">{{end}}
|
||||||
<script src="/s/init.js?i=10"></script>
|
<script src="/s/init.js?i=11"></script>
|
||||||
{{range .Header.ScriptsAsync}}
|
{{range .Header.ScriptsAsync}}
|
||||||
<script async src="/s/{{.}}"></script>{{end}}
|
<script async src="/s/{{.}}"></script>{{end}}
|
||||||
<script src="/s/jquery-3.1.1.min.js"></script>
|
<script src="/s/jquery-3.1.1.min.js"></script>
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
else $('.alert').insertAfter(".rowhead:first");
|
else $('.alert').insertAfter(".rowhead:first");
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("bf")
|
|
||||||
addInitHook("end_init", () => {
|
addInitHook("end_init", () => {
|
||||||
//console.log("af")
|
let loggedIn = document.head.querySelector("[property='x-mem']")!=null;
|
||||||
let loggedIn = document.head.querySelector("[property='x-loggedin']").content=="true";
|
|
||||||
if(loggedIn) {
|
if(loggedIn) {
|
||||||
if(navigator.userAgent.indexOf("Firefox") != -1) $.trumbowyg.svgPath = "/s/trumbowyg/ui/icons.svg";
|
if(navigator.userAgent.indexOf("Firefox")!=-1) $.trumbowyg.svgPath = "/s/trumbowyg/ui/icons.svg";
|
||||||
|
|
||||||
// Is there we way we can append instead? Maybe, an editor plugin?
|
// Is there we way we can append instead? Maybe, an editor plugin?
|
||||||
attachItemCallback = function(attachItem) {
|
attachItemCallback = function(attachItem) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="topic_row{{if .Sticky}} topic_sticky{{else if .IsClosed}} topic_closed{{end}}"data-tid={{.ID}}>
|
<div class="topic_row{{if .Sticky}} topic_sticky{{else if .IsClosed}} topic_closed{{end}}"data-tid={{.ID}}>
|
||||||
<div class="rowitem topic_left passive datarow">
|
<div class="rowitem topic_left passive datarow">
|
||||||
<a href="{{.Creator.Link}}"><img src="{{.Creator.MicroAvatar}}" height=64 alt="Avatar"title="{{.Creator.Name}}'s Avatar"aria-hidden="true"></a>
|
<a href="{{.Creator.Link}}"><img src="{{.Creator.MicroAvatar}}"height=64 alt="Avatar"title="{{.Creator.Name}}'s Avatar"aria-hidden="true"></a>
|
||||||
<span class="topic_inner_left">
|
<span class="topic_inner_left">
|
||||||
<span class="rowtopic"itemprop="itemListElement"title="{{.Title}}"><a href="{{.Link}}">{{.Title}}</a>{{if .ForumName}}<a class="parent_forum_sep">-</a><a href="{{.ForumLink}}"title="{{.ForumName}}"class="rowsmall parent_forum">{{.ForumName}}</a>{{end}}</span>
|
<span class="rowtopic"itemprop="itemListElement"title="{{.Title}}"><a href="{{.Link}}">{{.Title}}</a>{{if .ForumName}}<a class="parent_forum_sep">-</a><a href="{{.ForumLink}}"title="{{.ForumName}}"class="rowsmall parent_forum">{{.ForumName}}</a>{{end}}</span>
|
||||||
<br><a class="rowsmall starter"href="{{.Creator.Link}}"title="{{.Creator.Name}}">{{.Creator.Name}}</a>
|
<br><a class="rowsmall starter"href="{{.Creator.Link}}"title="{{.Creator.Name}}">{{.Creator.Name}}</a>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="rowitem topic_right passive datarow">
|
<div class="rowitem topic_right passive datarow">
|
||||||
<div class="topic_right_inside">
|
<div class="topic_right_inside">
|
||||||
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}" height=64 alt="Avatar"title="{{.LastUser.Name}}'s Avatar"aria-hidden="true"></a>
|
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}"height=64 alt="Avatar"title="{{.LastUser.Name}}'s Avatar"aria-hidden="true"></a>
|
||||||
<span>
|
<span>
|
||||||
<a href="{{.LastUser.Link}}"class="lastName"title="{{.LastUser.Name}}">{{.LastUser.Name}}</a><br>
|
<a href="{{.LastUser.Link}}"class="lastName"title="{{.LastUser.Name}}">{{.LastUser.Name}}</a><br>
|
||||||
<a href="{{.Link}}?page={{.LastPage}}{{if .LastReplyID}}#post-{{.LastReplyID}}{{end}}"class="rowsmall lastReplyAt"title="{{abstime .LastReplyAt}}">{{reltime .LastReplyAt}}</a>
|
<a href="{{.Link}}?page={{.LastPage}}{{if .LastReplyID}}#post-{{.LastReplyID}}{{end}}"class="rowsmall lastReplyAt"title="{{abstime .LastReplyAt}}">{{reltime .LastReplyAt}}</a>
|
||||||
|
|
|
@ -31,7 +31,6 @@ func StringToBytes(s string) (bytes []byte) {
|
||||||
runtime.KeepAlive(&s)
|
runtime.KeepAlive(&s)
|
||||||
return bytes
|
return bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
func BytesToString(bytes []byte) (s string) {
|
func BytesToString(bytes []byte) (s string) {
|
||||||
slice := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
|
slice := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
|
||||||
str := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
str := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||||
|
@ -40,11 +39,9 @@ func BytesToString(bytes []byte) (s string) {
|
||||||
runtime.KeepAlive(&bytes)
|
runtime.KeepAlive(&bytes)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
//go:linkname nanotime runtime.nanotime
|
//go:linkname nanotime runtime.nanotime
|
||||||
func nanotime() int64
|
func nanotime() int64
|
||||||
|
|
||||||
func Nanotime() int64 {
|
func Nanotime() int64 {
|
||||||
return nanotime()
|
return nanotime()
|
||||||
}*/
|
}*/
|
Loading…
Reference in New Issue