From cd667821291b8c7619215e1c09eda6d663bb95c3 Mon Sep 17 00:00:00 2001 From: Azareal Date: Sat, 28 Mar 2020 07:01:44 +1000 Subject: [PATCH] push content type for opensearch don't insert a last ip on installation save bytes and allocs in the parser add attach parser test cases more benchmarks --- common/parser.go | 12 ++--- general_test.go | 119 +++++++++++++++++++++++++++++++++++++++++++++ install/install.go | 2 +- parser_test.go | 42 ++++++++++------ routes/api.go | 1 + 5 files changed, 155 insertions(+), 21 deletions(-) diff --git a/common/parser.go b/common/parser.go index cef83a71..c3b319a3 100644 --- a/common/parser.go +++ b/common/parser.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "net/url" "os" + "path/filepath" "regexp" "strconv" "strings" @@ -24,7 +25,7 @@ var InvalidProfile = []byte("[Invalid Profile]") var InvalidForum = []byte("[Invalid Forum]") var unknownMedia = []byte("[Unknown Media]") var URLOpen = []byte("") var bytesSinglequote = []byte("'") var bytesGreaterthan = []byte(">") @@ -32,8 +33,8 @@ var urlMention = []byte(" class='mention'") var URLClose = []byte("") var imageOpen = []byte("") -var attachOpen = []byte("") +var attachOpen = []byte("Attachment") var sidParam = []byte("?sid=") var stypeParam = []byte("&stype=") @@ -914,12 +915,11 @@ func parseMediaString(data string, settings *ParseSettings) (media MediaEmbed, o sport = ":" + port } media.URL = scheme + "//" + host + sport + path - extarr := strings.Split(path, ".") - if len(extarr) == 0 { + ext := strings.TrimPrefix(filepath.Ext(path), ".") + if len(ext) == 0 { // TODO: Write a unit test for this return media, false } - ext := extarr[len(extarr)-1] if ImageFileExts.Contains(ext) { media.Type = "attach" } else { diff --git a/general_test.go b/general_test.go index a73d0c1d..bc0fb451 100644 --- a/general_test.go +++ b/general_test.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "net/http/httptest" + "runtime" "runtime/debug" "strconv" "strings" @@ -216,6 +217,10 @@ func BenchmarkTopicAdminRouteParallelAltAlt(b *testing.B) { BenchmarkTopicAdminRouteParallel(b) } +func BenchmarkTopicGuestAdminRouteParallelWithRouterPre(b *testing.B) { + runtime.GC() +} + func BenchmarkTopicGuestAdminRouteParallelWithRouter(b *testing.B) { binit(b) router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) @@ -236,6 +241,7 @@ func BenchmarkTopicGuestAdminRouteParallelWithRouter(b *testing.B) { uidCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: c.Year} sessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: c.Year} path := "/topic/hm." + benchTid + //runtime.GC() b.RunParallel(func(pb *testing.PB) { for pb.Next() { @@ -270,6 +276,67 @@ func BenchmarkTopicGuestAdminRouteParallelWithRouter(b *testing.B) { cfg.Restore() } +func BenchmarkTopicGuestAdminRouteParallelWithRouterPre2(b *testing.B) { + runtime.GC() +} + +func BenchmarkTopicGuestAdminRouteParallelWithRouterGC(b *testing.B) { + binit(b) + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) + if err != nil { + b.Fatal(err) + } + cfg := NewStashConfig() + c.Dev.DebugMode = false + c.Dev.SuperDebug = false + + admin, err := c.Users.Get(1) + if err != nil { + b.Fatal(err) + } + if !admin.IsAdmin { + b.Fatal("UID1 is not an admin") + } + uidCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: c.Year} + sessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: c.Year} + path := "/topic/hm." + benchTid + //runtime.GC() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + w := httptest.NewRecorder() + reqAdmin := httptest.NewRequest("get", path, bytes.NewReader(nil)) + reqAdmin.AddCookie(&uidCookie) + reqAdmin.AddCookie(&sessionCookie) + reqAdmin.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") + reqAdmin.Header.Set("Host", "localhost") + reqAdmin.Host = "localhost" + router.ServeHTTP(w, reqAdmin) + if w.Code != 200 { + b.Log(w.Body) + b.Fatal("HTTP Error!") + } + + { + w := httptest.NewRecorder() + req := httptest.NewRequest("GET", path, bytes.NewReader(nil)) + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") + req.Header.Set("Host", "localhost") + req.Host = "localhost" + router.ServeHTTP(w, req) + if w.Code != 200 { + b.Log(w.Body) + b.Fatal("HTTP Error!") + } + } + } + + runtime.GC() + }) + + cfg.Restore() +} + func BenchmarkTopicGuestRouteParallel(b *testing.B) { binit(b) cfg := NewStashConfig() @@ -324,6 +391,54 @@ func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) { cfg.Restore() } +func BenchmarkAlertsRouteAdminParallelWithRouterGCPre(b *testing.B) { + runtime.GC() +} + +func BenchmarkAlertsRouteAdminParallelWithRouterGC(b *testing.B) { + binit(b) + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) + if err != nil { + b.Fatal(err) + } + cfg := NewStashConfig() + c.Dev.DebugMode = false + c.Dev.SuperDebug = false + + admin, err := c.Users.Get(1) + if err != nil { + b.Fatal(err) + } + if !admin.IsAdmin { + b.Fatal("UID1 is not an admin") + } + uidCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: c.Year} + sessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: c.Year} + path := "/api/?m=alerts" + //runtime.GC() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + w := httptest.NewRecorder() + reqAdmin := httptest.NewRequest("get", path, bytes.NewReader(nil)) + reqAdmin.AddCookie(&uidCookie) + reqAdmin.AddCookie(&sessionCookie) + reqAdmin.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") + reqAdmin.Header.Set("Host", "localhost") + reqAdmin.Host = "localhost" + router.ServeHTTP(w, reqAdmin) + if w.Code != 200 { + b.Log(w.Body) + b.Fatal("HTTP Error!") + } + } + + runtime.GC() + }) + + cfg.Restore() +} + func obRoute(b *testing.B, path string) { binit(b) cfg := NewStashConfig() @@ -370,6 +485,10 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) { obRouteNoError(b, "/garble/haa") } +func BenchmarkAlertsRouteGuestParallelWithRouter(b *testing.B) { + obRoute(b, "/api/?m=alerts") +} + // TODO: Alternate between member and guest to bust some CPU caches? func binit(b *testing.B) { diff --git a/install/install.go b/install/install.go index c7a46f0b..e63b067c 100644 --- a/install/install.go +++ b/install/install.go @@ -37,7 +37,7 @@ func createAdmin() error { } // Build the admin user query - adminUserStmt, err := qgen.Builder.SimpleInsert("users", "name, password, salt, email, group, is_super_admin, active, createdAt, lastActiveAt, lastLiked, oldestItemLikedCreatedAt, message, last_ip", "'Admin',?,?,'admin@localhost',1,1,1,UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),'','127.0.0.1'") + adminUserStmt, err := qgen.Builder.SimpleInsert("users", "name, password, salt, email, group, is_super_admin, active, createdAt, lastActiveAt, lastLiked, oldestItemLikedCreatedAt, message, last_ip", "'Admin',?,?,'admin@localhost',1,1,1,UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''") if err != nil { return err } diff --git a/parser_test.go b/parser_test.go index 483c0d3d..0438d9c2 100644 --- a/parser_test.go +++ b/parser_test.go @@ -145,7 +145,7 @@ func TestParser(t *testing.T) { l := &METriList{nil} url := "github.com/Azareal/Gosora" - eurl := "" + url + "" + eurl := "" + url + "" l.Add("", "") l.Add("haha", "haha") l.Add("t", "t") @@ -194,18 +194,18 @@ func TestParser(t *testing.T) { l.Add("ss", "ss") l.Add("haha\nhaha\nhaha", "haha
haha
haha") l.Add("//"+url, eurl) - l.Add("//a", "a") - l.Add(" //a", " a") - l.Add("//a ", "a ") - l.Add(" //a ", " a ") - l.Add("d //a ", "d a ") - l.Add("ddd ddd //a ", "ddd ddd a ") - l.Add("https://"+url, ""+url+"") - l.Add("https://t", "t") - l.Add("http://"+url, ""+url+"") + l.Add("//a", "a") + l.Add(" //a", " a") + l.Add("//a ", "a ") + l.Add(" //a ", " a ") + l.Add("d //a ", "d a ") + l.Add("ddd ddd //a ", "ddd ddd a ") + l.Add("https://"+url, ""+url+"") + l.Add("https://t", "t") + l.Add("http://"+url, ""+url+"") l.Add("#http://"+url, "#http://"+url) l.Add("@http://"+url, "[Invalid Profile]ttp://"+url) - l.Add("//"+url+"\n", ""+url+"
") + l.Add("//"+url+"\n", ""+url+"
") l.Add("\n//"+url, "
"+eurl) l.Add("\n//"+url+"\n", "
"+eurl+"
") l.Add("\n//"+url+"\n\n", "
"+eurl+"

") @@ -222,10 +222,24 @@ func TestParser(t *testing.T) { fs = "https://" + c.Site.URL } l.Add("//"+u, ""+c.Site.URL+"") + + // TODO: Strip redundant slashes? + l.Add("//"+u+"/", ""+c.Site.URL+"/") + l.Add("//"+u+"//", ""+c.Site.URL+"//") + l.Add("//"+u+"\n", ""+c.Site.URL+"
") l.Add("//"+u+"\n//"+u, ""+c.Site.URL+"
"+c.Site.URL+"") l.Add("http://"+u, ""+c.Site.URL+"") l.Add("https://"+u, ""+c.Site.URL+"") + l.Add("//"+u+"/attachs/sha256hash.png?sid=1&stype=forums", "") + l.Add("//"+u+"/attachs/sha256hash?sid=1&stype=forums", "[Invalid URL]") + l.Add("//"+u+"/attachs/s?sid=1&stype=forums", "[Invalid URL]") + l.Add("//"+u+"/attachs/?sid=1&stype=forums", "[Invalid URL]") + l.Add("//"+u+"/attachs/sha256hash.?sid=1&stype=forums", "[Invalid URL]") + l.Add("//"+u+"/attachs?sid=1&stype=forums", "[Invalid URL]") + l.Add("//"+u+"/attachs/sha256hash.png", "") + l.Add("//"+u+"/attachs/sha256hash.png?sid=1", "") + l.Add("//"+u+"/attachs/sha256hash.png?stype=forums", "") } local("localhost") local("127.0.0.1") @@ -259,9 +273,9 @@ func TestParser(t *testing.T) { l.Add("@ #tid-@", "[Invalid Profile]#tid-@") l.Add("#tid-1 #tid-1", "#tid-1 #tid-1") l.Add("#tid-0", "[Invalid Topic]") - l.Add("https://"+url+"/#tid-1", ""+url+"/#tid-1") - l.Add("https://"+url+"/?hi=2", ""+url+"/?hi=2") - l.Add("https://"+url+"/?hi=2#t=1", ""+url+"/?hi=2#t=1") + l.Add("https://"+url+"/#tid-1", ""+url+"/#tid-1") + l.Add("https://"+url+"/?hi=2", ""+url+"/?hi=2") + l.Add("https://"+url+"/?hi=2#t=1", ""+url+"/?hi=2#t=1") l.Add("#fid-1", "#fid-1") l.Add(" #fid-1", " #fid-1") l.Add("#fid-0", "[Invalid Forum]") diff --git a/routes/api.go b/routes/api.go index 6f45ca4d..176ca80f 100644 --- a/routes/api.go +++ b/routes/api.go @@ -254,6 +254,7 @@ func APIMe(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { } func OpenSearchXml(w http.ResponseWriter, r *http.Request) c.RouteError { + w.Header().Set("Content-Type", "application/xml") furl := "http" if c.Config.SslSchema { furl += "s"