From 6fdf615cf5f460e9ffd8ea26a43606cc6d054067 Mon Sep 17 00:00:00 2001 From: Azareal Date: Wed, 15 Feb 2017 10:49:30 +0000 Subject: [PATCH] Topic and user edits should now update the caches. Ditto for topic deletions. The tests and benchmarks now run again. gloinit() is always called prior to the tests and benchmarks now. The tests and benchmarks no longer use hard-coded session strings for admin route tests. Added some new route tests. We now pull the database version into a variable. Fixed an issue with guest perms not applying properly. Tweaked the router to make it a little more efficient. Moved more topic / user parsing logic into CascadeGet Profiles now use the user cache. Added the Set method to the caches. Set is used when you don't know if an item exists in a cache or not. Added the Load method to the caches. Load is used to forcefully reload an item in a cache from the database. --- cache.go | 2 + files.go | 8 +- general_test.go | 528 +++++++------- images/postcache-tests-and-bench.PNG | Bin 0 -> 32126 bytes main.go | 45 +- mod_routes.go | 72 +- mysql.go | 5 + ...Bench-13-01-2017-doubled-gosoras-speed.PNG | Bin 0 -> 129169 bytes .../bench_parser_with_regexp.PNG | Bin {images => old-images}/bench_round1.PNG | Bin .../bench_round1_with_memory_allocs.PNG | Bin .../bench_round1_with_router_bench.PNG | Bin {images => old-images}/bench_round2.PNG | Bin {images => old-images}/bench_round3.PNG | Bin .../bench_round3_staticfileimprovements.PNG | Bin {images => old-images}/bench_round4.PNG | Bin {images => old-images}/bench_topic_route.PNG | Bin .../bench_vestigo_router.PNG | Bin permissions.go | 2 + router.go | 6 +- routes.go | 78 +-- template_forum.go | 2 +- template_forums.go | 2 +- template_topic.go | 2 +- templates.go | 1 + templates_old.go | 657 ------------------ topic.go | 46 +- user.go | 139 +++- 28 files changed, 563 insertions(+), 1032 deletions(-) create mode 100644 images/postcache-tests-and-bench.PNG create mode 100644 old-images/Bench-13-01-2017-doubled-gosoras-speed.PNG rename {images => old-images}/bench_parser_with_regexp.PNG (100%) rename {images => old-images}/bench_round1.PNG (100%) rename {images => old-images}/bench_round1_with_memory_allocs.PNG (100%) rename {images => old-images}/bench_round1_with_router_bench.PNG (100%) rename {images => old-images}/bench_round2.PNG (100%) rename {images => old-images}/bench_round3.PNG (100%) rename {images => old-images}/bench_round3_staticfileimprovements.PNG (100%) rename {images => old-images}/bench_round4.PNG (100%) rename {images => old-images}/bench_topic_route.PNG (100%) rename {images => old-images}/bench_vestigo_router.PNG (100%) delete mode 100644 templates_old.go diff --git a/cache.go b/cache.go index d716bd93..71b1ab45 100644 --- a/cache.go +++ b/cache.go @@ -11,9 +11,11 @@ var users UserStore var topics TopicStore type DataStore interface { + Load(id int) error Get(id int) (interface{}, error) GetUnsafe(id int) (interface{}, error) CascadeGet(id int) (interface{}, error) + Set(item interface{}) error Add(item interface{}) error AddUnsafe(item interface{}) error Remove(id int) error diff --git a/files.go b/files.go index 38ac39fd..0071419b 100644 --- a/files.go +++ b/files.go @@ -4,9 +4,9 @@ import "log" import "bytes" import "strings" import "mime" -import "errors" +//import "errors" import "os" -import "io" +//import "io" import "io/ioutil" import "path/filepath" import "net/http" @@ -23,7 +23,7 @@ type SFile struct FormattedModTime string } -func (r SFile) Read(b []byte) (n int, err error) { +/*func (r SFile) Read(b []byte) (n int, err error) { n = 0 if r.Pos > r.Length { return n, io.EOF @@ -58,7 +58,7 @@ func (r SFile) Seek(offset int64, whence int) (int64, error) { return 0, errors.New("invalid whence") } return r.Pos, nil -} +}*/ func add_static_file(path string, prefix string) error { data, err := ioutil.ReadFile(path) diff --git a/general_test.go b/general_test.go index bd85ba06..39eeb47a 100644 --- a/general_test.go +++ b/general_test.go @@ -1,5 +1,6 @@ package main import "os" +import "fmt" import "log" import "bytes" import "strconv" @@ -8,7 +9,6 @@ import "testing" import "net/http" import "net/http/httptest" import "io/ioutil" -import "html/template" import "database/sql" import _ "github.com/go-sql-driver/mysql" //import "github.com/husobee/vestigo" @@ -23,9 +23,25 @@ func gloinit() { //discard := ioutil.Discard //log.SetOutput(discard) + init_themes() var err error init_database(err) + init_templates() db.SetMaxOpenConns(64) + err = init_errors() + if err != nil { + log.Fatal(err) + } + + if cache_topicuser == CACHE_STATIC { + users = NewStaticUserStore(user_cache_capacity) + topics = NewStaticTopicStore(topic_cache_capacity) + } else { + users = NewSqlUserStore() + topics = NewSqlTopicStore() + } + + init_static_files() external_sites["YT"] = "https://www.youtube.com/" hooks["trow_assign"] = nil hooks["rrow_assign"] = nil @@ -33,26 +49,30 @@ func gloinit() { gloinited = true } -func BenchmarkTopicTemplate(b *testing.B) { +func init() { + gloinit() +} + +func BenchmarkTopicTemplateSerial(b *testing.B) { b.ReportAllocs() user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"} noticeList := []string{"test"} - topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"} + topic := TopicUser{Title: "Lol",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"} var replyList []Reply - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) - replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) + replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1}) tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false} tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false} @@ -113,24 +133,24 @@ func BenchmarkTopicTemplate(b *testing.B) { defer pprof.StopCPUProfile()*/ } -func BenchmarkTopicsTemplate(b *testing.B) { +func BenchmarkTopicsTemplateSerial(b *testing.B) { b.ReportAllocs() user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"} noticeList := []string{"test"} - var topicList []TopicUser - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) - topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + var topicList []TopicsRow + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) + topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) w := ioutil.Discard tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,nil} @@ -163,23 +183,6 @@ func BenchmarkStaticRouteParallel(b *testing.B) { if !gloinited { gloinit() } - - b.RunParallel(func(pb *testing.PB) { - static_w := httptest.NewRecorder() - static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) - static_handler := http.HandlerFunc(route_static) - for pb.Next() { - static_w.Body.Reset() - static_handler.ServeHTTP(static_w,static_req) - } - }) -} - -/*func BenchmarkStaticRouteParallelWithPlugins(b *testing.B) { - b.ReportAllocs() - if !gloinited { - gloinit() - } if !plugins_inited { init_plugins() } @@ -189,11 +192,16 @@ func BenchmarkStaticRouteParallel(b *testing.B) { static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) static_handler := http.HandlerFunc(route_static) for pb.Next() { + //static_w.Code = 200 static_w.Body.Reset() static_handler.ServeHTTP(static_w,static_req) + //if static_w.Code != 200 { + // fmt.Println(static_w.Body) + // panic("HTTP Error!") + //} } }) -}*/ +} func BenchmarkTopicAdminRouteParallel(b *testing.B) { b.ReportAllocs() @@ -202,9 +210,15 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) { } b.RunParallel(func(pb *testing.PB) { - admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year} - // TO-DO: Stop hard-coding this value. Seriously. - admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year} + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} topic_w := httptest.NewRecorder() topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) @@ -214,7 +228,7 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) { topic_handler := http.HandlerFunc(route_topic_id) for pb.Next() { - //topic_w.Body.Reset() + topic_w.Body.Reset() topic_handler.ServeHTTP(topic_w,topic_req_admin) } }) @@ -245,9 +259,15 @@ func BenchmarkForumsAdminRouteParallel(b *testing.B) { } b.RunParallel(func(pb *testing.PB) { - admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year} - // TO-DO: Stop hard-coding this value. Seriously. - admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year} + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} forums_w := httptest.NewRecorder() forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) @@ -270,9 +290,15 @@ func BenchmarkForumsAdminRouteParallelProf(b *testing.B) { } b.RunParallel(func(pb *testing.PB) { - admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year} - // TO-DO: Stop hard-coding this value. Seriously. - admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year} + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year} forums_w := httptest.NewRecorder() forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) @@ -313,10 +339,16 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) { func BenchmarkRoutesSerial(b *testing.B) { b.ReportAllocs() + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } - admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year} - // TO-DO: Stop hard-coding this value. Seriously. - admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year} + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year} if plugins_inited { b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on") @@ -367,8 +399,13 @@ func BenchmarkRoutesSerial(b *testing.B) { b.Run("static_recorder", func(b *testing.B) { for i := 0; i < b.N; i++ { + //static_w.Code = 200 static_w.Body.Reset() static_handler.ServeHTTP(static_w,static_req) + //if static_w.Code != 200 { + // fmt.Println(static_w.Body) + // panic("HTTP Error!") + //} } }) @@ -542,12 +579,9 @@ func BenchmarkQueryTopicParallel(b *testing.B) { } b.RunParallel(func(pb *testing.PB) { - topic := TopicUser{Css: no_css_tmpl} - var content string - var is_super_admin bool - var group int + tu := TopicUser{Css: no_css_tmpl} for pb.Next() { - err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress) + err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) if err == sql.ErrNoRows { log.Fatal("No rows found!") return @@ -566,12 +600,9 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) { } b.RunParallel(func(pb *testing.PB) { - topic := TopicUser{Css: no_css_tmpl} - var content string - var is_super_admin bool - var group int + tu := TopicUser{Css: no_css_tmpl} for pb.Next() { - err := get_topic_user_stmt.QueryRow(1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress) + err := get_topic_user_stmt.QueryRow(1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) if err == sql.ErrNoRows { log.Fatal("No rows found!") return @@ -585,13 +616,10 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) { func BenchmarkQueriesSerial(b *testing.B) { b.ReportAllocs() - topic := TopicUser{Css: no_css_tmpl} - var content string - var is_super_admin bool - var group int + tu := TopicUser{Css: no_css_tmpl} b.Run("topic", func(b *testing.B) { for i := 0; i < b.N; i++ { - err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress) + err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) if err == sql.ErrNoRows { log.Fatal("No rows found!") return @@ -617,7 +645,10 @@ func BenchmarkQueriesSerial(b *testing.B) { defer rows.Close() } }) + replyItem := Reply{Css: no_css_tmpl} + var is_super_admin bool + var group int b.Run("topic_replies_scan", func(b *testing.B) { for i := 0; i < b.N; i++ { rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?", 1) @@ -648,7 +679,7 @@ func addEmptyRoutesToMux(routes []string, serveMux *http.ServeMux) { } } -func BenchmarkDefaultGoRouter(b *testing.B) { +func BenchmarkDefaultGoRouterSerial(b *testing.B) { w := httptest.NewRecorder() req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) routes := make([]string, 0) @@ -805,176 +836,13 @@ func BenchmarkDefaultGoRouter(b *testing.B) { }) } -/*func addEmptyRoutesToVestigo(routes []string, router *vestigo.Router) { - for _, route := range routes { - router.HandleFunc(route, func(_ http.ResponseWriter,_ *http.Request){}) - } -} - -func BenchmarkVestigoRouter(b *testing.B) { - w := httptest.NewRecorder() - req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) - routes := make([]string, 0) - - routes = append(routes,"/test/") - router := vestigo.NewRouter() - router.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){}) - b.Run("one-route", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - routes = append(routes,"/topic/") - routes = append(routes,"/forums/") - routes = append(routes,"/forum/") - routes = append(routes,"/panel/") - router = vestigo.NewRouter() - addEmptyRoutesToVestigo(routes, router) - b.Run("five-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/panel/plugins/") - routes = append(routes,"/panel/groups/") - routes = append(routes,"/panel/settings/") - routes = append(routes,"/panel/users/") - routes = append(routes,"/panel/forums/") - addEmptyRoutesToVestigo(routes, router) - b.Run("ten-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/panel/forums/create/submit/") - routes = append(routes,"/panel/forums/delete/") - routes = append(routes,"/users/ban/") - routes = append(routes,"/panel/users/edit/") - routes = append(routes,"/panel/forums/create/") - routes = append(routes,"/users/unban/") - routes = append(routes,"/pages/") - routes = append(routes,"/users/activate/") - routes = append(routes,"/panel/forums/edit/submit/") - routes = append(routes,"/panel/plugins/activate/") - addEmptyRoutesToVestigo(routes, router) - b.Run("twenty-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/panel/plugins/deactivate/") - routes = append(routes,"/panel/plugins/install/") - routes = append(routes,"/panel/plugins/uninstall/") - routes = append(routes,"/panel/templates/") - routes = append(routes,"/panel/templates/edit/") - routes = append(routes,"/panel/templates/create/") - routes = append(routes,"/panel/templates/delete/") - routes = append(routes,"/panel/templates/edit/submit/") - routes = append(routes,"/panel/themes/") - routes = append(routes,"/panel/themes/edit/") - addEmptyRoutesToVestigo(routes, router) - b.Run("thirty-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/panel/themes/create/") - routes = append(routes,"/panel/themes/delete/") - routes = append(routes,"/panel/themes/delete/submit/") - routes = append(routes,"/panel/templates/create/submit/") - routes = append(routes,"/panel/templates/delete/submit/") - routes = append(routes,"/panel/widgets/") - routes = append(routes,"/panel/widgets/edit/") - routes = append(routes,"/panel/widgets/activate/") - routes = append(routes,"/panel/widgets/deactivate/") - routes = append(routes,"/panel/magical/wombat/path") - addEmptyRoutesToVestigo(routes, router) - b.Run("forty-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/report/") - routes = append(routes,"/report/submit/") - routes = append(routes,"/topic/create/submit/") - routes = append(routes,"/topics/create/") - routes = append(routes,"/overview/") - routes = append(routes,"/uploads/") - routes = append(routes,"/static/") - routes = append(routes,"/reply/edit/submit/") - routes = append(routes,"/reply/delete/submit/") - routes = append(routes,"/topic/edit/submit/") - addEmptyRoutesToVestigo(routes, router) - b.Run("fifty-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/topic/delete/submit/") - routes = append(routes,"/topic/stick/submit/") - routes = append(routes,"/topic/unstick/submit/") - routes = append(routes,"/accounts/login/") - routes = append(routes,"/accounts/create/") - routes = append(routes,"/accounts/logout/") - routes = append(routes,"/accounts/login/submit/") - routes = append(routes,"/accounts/create/submit/") - routes = append(routes,"/user/edit/critical/") - routes = append(routes,"/user/edit/critical/submit/") - addEmptyRoutesToVestigo(routes, router) - b.Run("sixty-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) - - router = vestigo.NewRouter() - routes = append(routes,"/user/edit/avatar/") - routes = append(routes,"/user/edit/avatar/submit/") - routes = append(routes,"/user/edit/username/") - routes = append(routes,"/user/edit/username/submit/") - routes = append(routes,"/profile/reply/create/") - routes = append(routes,"/profile/reply/edit/submit/") - routes = append(routes,"/profile/reply/delete/submit/") - routes = append(routes,"/arcane/tower/") - routes = append(routes,"/magical/kingdom/") - routes = append(routes,"/insert/name/here/") - addEmptyRoutesToVestigo(routes, router) - b.Run("seventy-routes", func(b *testing.B) { - for i := 0; i < b.N; i++ { - req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil)) - router.ServeHTTP(w,req) - } - }) -}*/ - func addEmptyRoutesToCustom(routes []string, router *Router) { for _, route := range routes { router.HandleFunc(route, func(_ http.ResponseWriter,_ *http.Request){}) } } -func BenchmarkCustomRouter(b *testing.B) { +func BenchmarkCustomRouterSerial(b *testing.B) { w := httptest.NewRecorder() req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) routes := make([]string, 0) @@ -1131,7 +999,7 @@ func BenchmarkCustomRouter(b *testing.B) { }) } -func BenchmarkParser(b *testing.B) { +func BenchmarkParserSerial(b *testing.B) { b.ReportAllocs() b.Run("empty_post", func(b *testing.B) { for i := 0; i < b.N; i++ { @@ -1165,7 +1033,7 @@ func BenchmarkParser(b *testing.B) { }) } -func BenchmarkBBCodePluginWithRegexp(b *testing.B) { +func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) { b.ReportAllocs() b.Run("empty_post", func(b *testing.B) { for i := 0; i < b.N; i++ { @@ -1214,7 +1082,7 @@ func BenchmarkBBCodePluginWithRegexp(b *testing.B) { }) } -func BenchmarkBBCodePluginWithoutCodeTag(b *testing.B) { +func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) { b.ReportAllocs() b.Run("empty_post", func(b *testing.B) { for i := 0; i < b.N; i++ { @@ -1263,7 +1131,7 @@ func BenchmarkBBCodePluginWithoutCodeTag(b *testing.B) { }) } -func BenchmarkBBCodePluginWithFullParser(b *testing.B) { +func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) { b.ReportAllocs() b.Run("empty_post", func(b *testing.B) { for i := 0; i < b.N; i++ { @@ -1320,6 +1188,186 @@ func TestLevels(t *testing.T) { } } +func TestStaticRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + static_w := httptest.NewRecorder() + static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) + static_handler := http.HandlerFunc(route_static) + + static_handler.ServeHTTP(static_w,static_req) + if static_w.Code != 200 { + fmt.Println(static_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the static route!") +} + +func TestTopicAdminRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} + + topic_w := httptest.NewRecorder() + topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) + topic_req_admin := topic_req + topic_req_admin.AddCookie(&admin_uid_cookie) + topic_req_admin.AddCookie(&admin_session_cookie) + topic_handler := http.HandlerFunc(route_topic_id) + + topic_handler.ServeHTTP(topic_w,topic_req_admin) + if topic_w.Code != 200 { + fmt.Println(topic_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the topic-admin route!") +} + +func TestTopicGuestRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + topic_w := httptest.NewRecorder() + topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) + topic_handler := http.HandlerFunc(route_topic_id) + + topic_handler.ServeHTTP(topic_w,topic_req) + if topic_w.Code != 200 { + fmt.Println(topic_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the topic-guest route!") +} + +func TestForumsAdminRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} + + forums_w := httptest.NewRecorder() + forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) + forums_req_admin := forums_req + forums_req_admin.AddCookie(&admin_uid_cookie) + forums_req_admin.AddCookie(&admin_session_cookie) + forums_handler := http.HandlerFunc(route_forums) + + forums_handler.ServeHTTP(forums_w,forums_req_admin) + if forums_w.Code != 200 { + fmt.Println(forums_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the forums-admin route!") +} + +func TestForumsGuestRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + forums_w := httptest.NewRecorder() + forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) + forums_handler := http.HandlerFunc(route_forums) + + forums_handler.ServeHTTP(forums_w,forums_req) + if forums_w.Code != 200 { + fmt.Println(forums_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the forums-guest route!") +} + +func TestForumAdminRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + admin, err := users.CascadeGet(1) + if err != nil { + panic(err) + } + if !admin.Is_Admin { + panic("UID1 is not an admin") + } + admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} + admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} + + forum_w := httptest.NewRecorder() + forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil)) + forum_req_admin := forum_req + forum_req_admin.AddCookie(&admin_uid_cookie) + forum_req_admin.AddCookie(&admin_session_cookie) + forum_handler := http.HandlerFunc(route_forum) + + forum_handler.ServeHTTP(forum_w,forum_req_admin) + if forum_w.Code != 200 { + fmt.Println(forum_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the forum-admin route!") +} + +func TestForumGuestRoute(t *testing.T) { + if !gloinited { + gloinit() + } + if !plugins_inited { + init_plugins() + } + + forum_w := httptest.NewRecorder() + forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil)) + forum_handler := http.HandlerFunc(route_forum) + + forum_handler.ServeHTTP(forum_w,forum_req) + if forum_w.Code != 200 { + fmt.Println(forum_w.Body) + panic("HTTP Error!") + } + fmt.Println("No problems found in the forum-guest route!") +} + /*func TestRoute(t *testing.T) { }*/ \ No newline at end of file diff --git a/images/postcache-tests-and-bench.PNG b/images/postcache-tests-and-bench.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f89a93eb26ecc7639ba4236f4c7edee966c12741 GIT binary patch literal 32126 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 literal 0 HcmV?d00001 diff --git a/main.go b/main.go index 87896959..d1da4da6 100644 --- a/main.go +++ b/main.go @@ -123,6 +123,29 @@ func init_templates() { template.Must(templates.ParseGlob("pages/*")) } +func init_static_files() { + log.Print("Loading the static files.") + err := filepath.Walk("./public", func(path string, f os.FileInfo, err error) error { + if f.IsDir() { + return nil + } + + path = strings.Replace(path,"\\","/",-1) + data, err := ioutil.ReadFile(path) + if err != nil { + return err + } + + path = strings.TrimPrefix(path,"public/") + log.Print("Added the '" + path + "' static file.") + static_files["/static/" + path] = SFile{data,compress_bytes_gzip(data),0,int64(len(data)),mime.TypeByExtension(filepath.Ext("/public/" + path)),f,f.ModTime().UTC().Format(http.TimeFormat)} + return nil + }) + if err != nil { + log.Fatal(err) + } +} + func main(){ //if profiling { // f, err := os.Create("startup_cpu.prof") @@ -151,27 +174,7 @@ func main(){ topics = NewSqlTopicStore() } - log.Print("Loading the static files.") - err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error { - if f.IsDir() { - return nil - } - - path = strings.Replace(path,"\\","/",-1) - data, err := ioutil.ReadFile(path) - if err != nil { - return err - } - - path = strings.TrimPrefix(path,"public/") - log.Print("Added the '" + path + "' static file.") - static_files["/static/" + path] = SFile{data,compress_bytes_gzip(data),0,int64(len(data)),mime.TypeByExtension(filepath.Ext("/public/" + path)),f,f.ModTime().UTC().Format(http.TimeFormat)} - return nil - }) - if err != nil { - log.Fatal(err) - } - + init_static_files() external_sites["YT"] = "https://www.youtube.com/" hooks["trow_assign"] = nil hooks["rrow_assign"] = nil diff --git a/mod_routes.go b/mod_routes.go index d6feb1f4..93518f6f 100644 --- a/mod_routes.go +++ b/mod_routes.go @@ -57,6 +57,12 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) { return } + err = topics.Load(tid) + if err != nil { + LocalError("This topic no longer exists!",w,r,user) + return + } + if is_js == "0" { http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther) } else { @@ -114,6 +120,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) { } forums[fid].TopicCount -= 1 + topics.Remove(tid) } func route_stick_topic(w http.ResponseWriter, r *http.Request) { @@ -123,8 +130,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) { return } - var fid int - err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid) + topic, err := topics.CascadeGet(tid) if err == sql.ErrNoRows { PreError("The topic you tried to pin doesn't exist.",w,r) return @@ -133,7 +139,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) { return } - user, ok := SimpleForumSessionCheck(w,r,fid) + user, ok := SimpleForumSessionCheck(w,r,topic.ParentID) if !ok { return } @@ -147,6 +153,8 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) { InternalError(err,w,r) return } + + topic.Sticky = true http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther) } @@ -157,8 +165,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) { return } - var fid int - err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid) + topic, err := topics.CascadeGet(tid) if err == sql.ErrNoRows { PreError("The topic you tried to unpin doesn't exist.",w,r) return @@ -167,7 +174,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) { return } - user, ok := SimpleForumSessionCheck(w,r,fid) + user, ok := SimpleForumSessionCheck(w,r,topic.ParentID) if !ok { return } @@ -181,6 +188,8 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) { InternalError(err,w,r) return } + + topic.Sticky = false http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther) } @@ -312,6 +321,12 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) { if err != nil { InternalErrorJSQ(err,w,r,is_js) } + + err = topics.Load(tid) + if err != nil { + LocalError("This topic no longer exists!",w,r,user) + return + } } func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) { @@ -374,7 +389,6 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) { LocalError("Bad Form",w,r,user) return } - is_js := r.PostFormValue("is_js") if is_js == "" { is_js = "0" @@ -387,7 +401,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) { } var uid int - err = db.QueryRow("SELECT uid from users_replies where rid = ?", rid).Scan(&uid) + err = db.QueryRow("select uid from users_replies where rid = ?", rid).Scan(&uid) if err == sql.ErrNoRows { LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js) return @@ -502,6 +516,12 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) { InternalError(err,w,r) return } + + err = users.Load(uid) + if err != nil { + LocalError("This user no longer exists!",w,r,user) + return + } http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther) } @@ -546,6 +566,12 @@ func route_unban(w http.ResponseWriter, r *http.Request) { InternalError(err,w,r) return } + + err = users.Load(uid) + if err != nil { + LocalError("This user no longer exists!",w,r,user) + return + } http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther) } @@ -595,6 +621,12 @@ func route_activate(w http.ResponseWriter, r *http.Request) { InternalError(err,w,r) return } + + err = users.Load(uid) + if err != nil { + LocalError("This user no longer exists!",w,r,user) + return + } http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther) } @@ -973,7 +1005,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) { sname := r.URL.Path[len("/panel/settings/edit/submit/"):] scontent := r.PostFormValue("setting-value") - err = db.QueryRow("SELECT name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints) + err = db.QueryRow("select name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints) if err == sql.ErrNoRows { LocalError("The setting you want to edit doesn't exist.",w,r,user) return @@ -1208,15 +1240,13 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){ return } - var err error - targetUser := User{ID: 0,} - targetUser.ID, err = strconv.Atoi(r.URL.Path[len("/panel/users/edit/"):]) + uid, err := strconv.Atoi(r.URL.Path[len("/panel/users/edit/"):]) if err != nil { LocalError("The provided User ID is not a valid number.",w,r,user) return } - err = db.QueryRow("select `name`,`email`,`group` from `users` where `uid` = ?", targetUser.ID).Scan(&targetUser.Name,&targetUser.Email,&targetUser.Group) + targetUser, err := users.Get(uid) if err == sql.ErrNoRows { LocalError("The user you're trying to edit doesn't exist.",w,r,user) return @@ -1225,8 +1255,6 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){ return } - targetUser.Is_Admin = targetUser.Is_Super_Admin || groups[targetUser.Group].Is_Admin - targetUser.Is_Super_Mod = groups[targetUser.Group].Is_Mod || targetUser.Is_Admin if targetUser.Is_Admin && !user.Is_Admin { LocalError("Only administrators can edit the account of an administrator.",w,r,user) return @@ -1264,15 +1292,13 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){ return } - var err error - targetUser := User{ID: 0,} - targetUser.ID, err = strconv.Atoi(r.URL.Path[len("/panel/users/edit/submit/"):]) + tid, err := strconv.Atoi(r.URL.Path[len("/panel/users/edit/submit/"):]) if err != nil { LocalError("The provided User ID is not a valid number.",w,r,user) return } - err = db.QueryRow("select `name`,`email`,`group` from `users` where `uid` = ?", targetUser.ID).Scan(&targetUser.Name, &targetUser.Email, &targetUser.Group) + targetUser, err := users.Get(tid) if err == sql.ErrNoRows { LocalError("The user you're trying to edit doesn't exist.",w,r,user) return @@ -1281,8 +1307,6 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){ return } - targetUser.Is_Admin = targetUser.Is_Super_Admin || groups[targetUser.Group].Is_Admin - targetUser.Is_Super_Mod = groups[targetUser.Group].Is_Mod || targetUser.Is_Admin if targetUser.Is_Admin && !user.Is_Admin { LocalError("Only administrators can edit the account of an administrator.",w,r,user) return @@ -1340,6 +1364,12 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){ SetPassword(targetUser.ID, newpassword) } + err = users.Load(targetUser.ID) + if err != nil { + LocalError("This user no longer exists!",w,r,user) + return + } + http.Redirect(w,r,"/panel/users/edit/" + strconv.Itoa(targetUser.ID),http.StatusSeeOther) } diff --git a/mysql.go b/mysql.go index 17bb2b45..a0ab9e60 100644 --- a/mysql.go +++ b/mysql.go @@ -9,6 +9,8 @@ import "strconv" import "encoding/json" var db *sql.DB +var db_version string + var get_user_stmt *sql.Stmt var get_full_user_stmt *sql.Stmt var get_topic_list_stmt *sql.Stmt @@ -92,6 +94,9 @@ func init_database(err error) { log.Fatal(err) } + // Getting the database version.. + db.QueryRow("SELECT VERSION()").Scan(&db_version) + /*log.Print("Preparing get_session statement.") get_session_stmt, err = db.Prepare("select `uid`,`name`,`group`,`is_super_admin`,`session`,`email`,`avatar`,`message`,`url_prefix`,`url_name`,`level`,`score`,`last_ip` from `users` where `uid` = ? and `session` = ? AND `session` <> ''") if err != nil { diff --git a/old-images/Bench-13-01-2017-doubled-gosoras-speed.PNG b/old-images/Bench-13-01-2017-doubled-gosoras-speed.PNG new file mode 100644 index 0000000000000000000000000000000000000000..9001831c5d6911e429848904dc7bbd08c2c97582 GIT binary patch literal 129169 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 sts.capacity { + sts.mu.Unlock() + return ErrStoreCapacityOverflow + } else { + sts.items[item.ID] = item + } + sts.mu.Unlock() + sts.length++ + return nil +} + func (sts *StaticTopicStore) Add(item *Topic) error { if sts.length >= sts.capacity { return ErrStoreCapacityOverflow @@ -218,7 +245,16 @@ func (sus *SqlTopicStore) CascadeGet(id int) (*Topic, error) { return &topic, err } +func (sus *SqlTopicStore) Load(id int) error { + topic := Topic{ID:id} + err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount) + return err +} + // Placeholder methods, the actual queries are done elsewhere +func (sus *SqlTopicStore) Set(item *Topic) error { + return nil +} func (sus *SqlTopicStore) Add(item *Topic) error { return nil } @@ -252,6 +288,7 @@ func get_topicuser(tid int) (TopicUser,error) { if err != nil { return TopicUser{ID:tid}, err } + init_user_perms(user) // We might be better off just passing seperate topic and user structs to the caller? return copy_topic_to_topicuser(topic, user), nil @@ -264,13 +301,8 @@ func get_topicuser(tid int) (TopicUser,error) { if err != nil { return TopicUser{ID:tid}, err } + init_user_perms(user) tu := copy_topic_to_topicuser(topic, user) - //fmt.Printf("%+v\n", topic) - //fmt.Println("") - //fmt.Printf("%+v\n", user) - //fmt.Println("") - //fmt.Printf("%+v\n", tu) - //fmt.Println("") return tu, nil } } @@ -280,7 +312,9 @@ func get_topicuser(tid int) (TopicUser,error) { the_topic := Topic{ID:tu.ID, Title:tu.Title, Content:tu.Content, CreatedBy:tu.CreatedBy, Is_Closed:tu.Is_Closed, Sticky:tu.Sticky, CreatedAt:tu.CreatedAt, LastReplyAt:tu.LastReplyAt, ParentID:tu.ParentID, IpAddress:tu.IpAddress, PostCount:tu.PostCount, LikeCount:tu.LikeCount} //fmt.Printf("%+v\n", the_topic) + tu.Tag = groups[tu.Group].Tag topics.Add(&the_topic) + //err = errors.Error("Loaded data via query") return tu, err } diff --git a/user.go b/user.go index 602fd3f8..1fb3ebf8 100644 --- a/user.go +++ b/user.go @@ -9,6 +9,8 @@ import "golang.org/x/crypto/bcrypt" import "database/sql" import _ "github.com/go-sql-driver/mysql" +var guest_user User = User{ID:0,Group:6,Perms:GuestPerms} + type User struct { ID int @@ -44,9 +46,11 @@ type Email struct } type UserStore interface { + Load(id int) error Get(id int) (*User, error) GetUnsafe(id int) (*User, error) CascadeGet(id int) (*User, error) + Set(item *User) error Add(item *User) error AddUnsafe(item *User) error Remove(id int) error @@ -94,12 +98,58 @@ func (sts *StaticUserStore) CascadeGet(id int) (*User, error) { user = &User{ID:id} err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + + if user.Avatar != "" { + if user.Avatar[0] == '.' { + user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar + } + } else { + user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) + } + user.Tag = groups[user.Group].Tag + init_user_perms(user) if err == nil { sts.Add(user) } return user, err } +func (sts *StaticUserStore) Load(id int) error { + user := &User{ID:id} + err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + if err != nil { + return err + } + + if user.Avatar != "" { + if user.Avatar[0] == '.' { + user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar + } + } else { + user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) + } + user.Tag = groups[user.Group].Tag + init_user_perms(user) + sts.Set(user) + return nil +} + +func (sts *StaticUserStore) Set(item *User) error { + sts.mu.Lock() + item, ok := sts.items[item.ID] + if ok { + sts.items[item.ID] = item + } else if sts.length >= sts.capacity { + sts.mu.Unlock() + return ErrStoreCapacityOverflow + } else { + sts.items[item.ID] = item + } + sts.mu.Unlock() + sts.length++ + return nil +} + func (sts *StaticUserStore) Add(item *User) error { if sts.length >= sts.capacity { return ErrStoreCapacityOverflow @@ -161,22 +211,62 @@ func NewSqlUserStore() *SqlUserStore { func (sus *SqlUserStore) Get(id int) (*User, error) { user := User{ID:id} err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + + if user.Avatar != "" { + if user.Avatar[0] == '.' { + user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar + } + } else { + user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) + } + user.Tag = groups[user.Group].Tag + init_user_perms(&user) return &user, err } func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) { user := User{ID:id} err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + + if user.Avatar != "" { + if user.Avatar[0] == '.' { + user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar + } + } else { + user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) + } + user.Tag = groups[user.Group].Tag + init_user_perms(&user) return &user, err } func (sus *SqlUserStore) CascadeGet(id int) (*User, error) { user := User{ID:id} err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + + if user.Avatar != "" { + if user.Avatar[0] == '.' { + user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar + } + } else { + user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) + } + user.Tag = groups[user.Group].Tag + init_user_perms(&user) return &user, err } +func (sus *SqlUserStore) Load(id int) error { + user := &User{ID:id} + // Simplify this into a quick check whether the user exists + err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP) + return err +} + // Placeholder methods, the actual queries are done elsewhere +func (sus *SqlUserStore) Set(item *User) error { + return nil +} func (sus *SqlUserStore) Add(item *User) error { return nil } @@ -258,6 +348,8 @@ func ForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user Us } user, success = SimpleSessionCheck(w,r) fperms := groups[user.Group].Forums[fid] + //fmt.Printf("%+v\n", user.Perms) + //fmt.Printf("%+v\n", fperms) if fperms.Overrides && !user.Is_Super_Admin { user.Perms.ViewTopic = fperms.ViewTopic user.Perms.LikeItem = fperms.LikeItem @@ -288,45 +380,28 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) { // Are there any session cookies..? cookie, err := r.Cookie("uid") if err != nil { - return User{ID:0,Group:6,Perms:GuestPerms}, true + return guest_user, true } uid, err := strconv.Atoi(cookie.Value) if err != nil { - return User{ID:0,Group:6,Perms:GuestPerms}, true + return guest_user, true } cookie, err = r.Cookie("session") if err != nil { - return User{ID:0,Group:6,Perms:GuestPerms}, true + return guest_user, true } // Is this session valid..? user, err := users.CascadeGet(uid) if err == sql.ErrNoRows { - user.ID = 0 - user.Session = "" - user.Group = 6 - user.Perms = GuestPerms - return *user, true + return guest_user, true } else if err != nil { InternalError(err,w,r) - return *user, false + return guest_user, false } if user.Session == "" || cookie.Value != user.Session { - user.ID = 0 - user.Session = "" - user.Group = 6 - user.Perms = GuestPerms - return *user, true - } - - user.Is_Admin = user.Is_Super_Admin || groups[user.Group].Is_Admin - user.Is_Super_Mod = groups[user.Group].Is_Mod || user.Is_Admin - user.Is_Mod = user.Is_Super_Mod - user.Is_Banned = groups[user.Group].Is_Banned - user.Loggedin = !user.Is_Banned || user.Is_Super_Mod - if user.Is_Banned && user.Is_Super_Mod { - user.Is_Banned = false + return guest_user, true } if user.Is_Super_Admin { @@ -335,14 +410,6 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) { user.Perms = groups[user.Group].Perms } - if user.Avatar != "" { - if user.Avatar[0] == '.' { - user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar - } - } else { - user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) - } - host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { PreError("Bad IP",w,r) @@ -448,3 +515,13 @@ func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error _, err = update_user_level_stmt.Exec(getLevel(user.Score - base_score - mod), uid) return err } + +func init_user_perms(user *User) { + user.Is_Admin = user.Is_Super_Admin || groups[user.Group].Is_Admin + user.Is_Super_Mod = user.Is_Admin || groups[user.Group].Is_Mod + user.Is_Mod = user.Is_Super_Mod + user.Is_Banned = groups[user.Group].Is_Banned + if user.Is_Banned && user.Is_Super_Mod { + user.Is_Banned = false + } +} \ No newline at end of file