gosora/gen_router.go

2189 lines
64 KiB
Go

// Code generated by Gosora's Router Generator. DO NOT EDIT.
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main
import (
"log"
"strings"
"bytes"
"strconv"
"compress/gzip"
"sync"
"sync/atomic"
"errors"
"os"
"net/http"
"github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/routes"
"github.com/Azareal/Gosora/routes/panel"
)
var ErrNoRoute = errors.New("That route doesn't exist.")
// TODO: What about the /uploads/ route? x.x
var RouteMap = map[string]interface{}{
"routes.Overview": routes.Overview,
"routes.CustomPage": routes.CustomPage,
"routes.ForumList": routes.ForumList,
"routes.ViewForum": routes.ViewForum,
"routes.ChangeTheme": routes.ChangeTheme,
"routes.ShowAttachment": routes.ShowAttachment,
"common.RouteWebsockets": common.RouteWebsockets,
"routeAPIPhrases": routeAPIPhrases,
"routes.APIMe": routes.APIMe,
"routeJSAntispam": routeJSAntispam,
"routeAPI": routeAPI,
"routes.ReportSubmit": routes.ReportSubmit,
"routes.TopicListMostViewed": routes.TopicListMostViewed,
"routes.CreateTopic": routes.CreateTopic,
"routes.TopicList": routes.TopicList,
"panel.Forums": panel.Forums,
"panel.ForumsCreateSubmit": panel.ForumsCreateSubmit,
"panel.ForumsDelete": panel.ForumsDelete,
"panel.ForumsDeleteSubmit": panel.ForumsDeleteSubmit,
"panel.ForumsEdit": panel.ForumsEdit,
"panel.ForumsEditSubmit": panel.ForumsEditSubmit,
"panel.ForumsEditPermsSubmit": panel.ForumsEditPermsSubmit,
"panel.ForumsEditPermsAdvance": panel.ForumsEditPermsAdvance,
"panel.ForumsEditPermsAdvanceSubmit": panel.ForumsEditPermsAdvanceSubmit,
"panel.Settings": panel.Settings,
"panel.SettingEdit": panel.SettingEdit,
"panel.SettingEditSubmit": panel.SettingEditSubmit,
"panel.WordFilters": panel.WordFilters,
"panel.WordFiltersCreateSubmit": panel.WordFiltersCreateSubmit,
"panel.WordFiltersEdit": panel.WordFiltersEdit,
"panel.WordFiltersEditSubmit": panel.WordFiltersEditSubmit,
"panel.WordFiltersDeleteSubmit": panel.WordFiltersDeleteSubmit,
"panel.Pages": panel.Pages,
"panel.PagesCreateSubmit": panel.PagesCreateSubmit,
"panel.PagesEdit": panel.PagesEdit,
"panel.PagesEditSubmit": panel.PagesEditSubmit,
"panel.PagesDeleteSubmit": panel.PagesDeleteSubmit,
"panel.Themes": panel.Themes,
"panel.ThemesSetDefault": panel.ThemesSetDefault,
"panel.ThemesMenus": panel.ThemesMenus,
"panel.ThemesMenusEdit": panel.ThemesMenusEdit,
"panel.ThemesMenuItemEdit": panel.ThemesMenuItemEdit,
"panel.ThemesMenuItemEditSubmit": panel.ThemesMenuItemEditSubmit,
"panel.ThemesMenuItemCreateSubmit": panel.ThemesMenuItemCreateSubmit,
"panel.ThemesMenuItemDeleteSubmit": panel.ThemesMenuItemDeleteSubmit,
"panel.ThemesMenuItemOrderSubmit": panel.ThemesMenuItemOrderSubmit,
"panel.ThemesWidgets": panel.ThemesWidgets,
"panel.ThemesWidgetsEditSubmit": panel.ThemesWidgetsEditSubmit,
"panel.ThemesWidgetsCreateSubmit": panel.ThemesWidgetsCreateSubmit,
"panel.ThemesWidgetsDeleteSubmit": panel.ThemesWidgetsDeleteSubmit,
"panel.Plugins": panel.Plugins,
"panel.PluginsActivate": panel.PluginsActivate,
"panel.PluginsDeactivate": panel.PluginsDeactivate,
"panel.PluginsInstall": panel.PluginsInstall,
"panel.Users": panel.Users,
"panel.UsersEdit": panel.UsersEdit,
"panel.UsersEditSubmit": panel.UsersEditSubmit,
"panel.AnalyticsViews": panel.AnalyticsViews,
"panel.AnalyticsRoutes": panel.AnalyticsRoutes,
"panel.AnalyticsAgents": panel.AnalyticsAgents,
"panel.AnalyticsSystems": panel.AnalyticsSystems,
"panel.AnalyticsLanguages": panel.AnalyticsLanguages,
"panel.AnalyticsReferrers": panel.AnalyticsReferrers,
"panel.AnalyticsRouteViews": panel.AnalyticsRouteViews,
"panel.AnalyticsAgentViews": panel.AnalyticsAgentViews,
"panel.AnalyticsForumViews": panel.AnalyticsForumViews,
"panel.AnalyticsSystemViews": panel.AnalyticsSystemViews,
"panel.AnalyticsLanguageViews": panel.AnalyticsLanguageViews,
"panel.AnalyticsReferrerViews": panel.AnalyticsReferrerViews,
"panel.AnalyticsPosts": panel.AnalyticsPosts,
"panel.AnalyticsTopics": panel.AnalyticsTopics,
"panel.AnalyticsForums": panel.AnalyticsForums,
"panel.Groups": panel.Groups,
"panel.GroupsEdit": panel.GroupsEdit,
"panel.GroupsEditPerms": panel.GroupsEditPerms,
"panel.GroupsEditSubmit": panel.GroupsEditSubmit,
"panel.GroupsEditPermsSubmit": panel.GroupsEditPermsSubmit,
"panel.GroupsCreateSubmit": panel.GroupsCreateSubmit,
"panel.Backups": panel.Backups,
"panel.LogsRegs": panel.LogsRegs,
"panel.LogsMod": panel.LogsMod,
"panel.Debug": panel.Debug,
"panel.Dashboard": panel.Dashboard,
"routes.AccountEdit": routes.AccountEdit,
"routes.AccountEditPassword": routes.AccountEditPassword,
"routes.AccountEditPasswordSubmit": routes.AccountEditPasswordSubmit,
"routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit,
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
"routes.AccountEditMFA": routes.AccountEditMFA,
"routes.AccountEditMFASetup": routes.AccountEditMFASetup,
"routes.AccountEditMFASetupSubmit": routes.AccountEditMFASetupSubmit,
"routes.AccountEditMFADisableSubmit": routes.AccountEditMFADisableSubmit,
"routes.AccountEditEmail": routes.AccountEditEmail,
"routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit,
"routes.AccountLogins": routes.AccountLogins,
"routes.LevelList": routes.LevelList,
"routes.ViewProfile": routes.ViewProfile,
"routes.BanUserSubmit": routes.BanUserSubmit,
"routes.UnbanUser": routes.UnbanUser,
"routes.ActivateUser": routes.ActivateUser,
"routes.IPSearch": routes.IPSearch,
"routes.CreateTopicSubmit": routes.CreateTopicSubmit,
"routes.EditTopicSubmit": routes.EditTopicSubmit,
"routes.DeleteTopicSubmit": routes.DeleteTopicSubmit,
"routes.StickTopicSubmit": routes.StickTopicSubmit,
"routes.UnstickTopicSubmit": routes.UnstickTopicSubmit,
"routes.LockTopicSubmit": routes.LockTopicSubmit,
"routes.UnlockTopicSubmit": routes.UnlockTopicSubmit,
"routes.MoveTopicSubmit": routes.MoveTopicSubmit,
"routes.LikeTopicSubmit": routes.LikeTopicSubmit,
"routes.AddAttachToTopicSubmit": routes.AddAttachToTopicSubmit,
"routes.RemoveAttachFromTopicSubmit": routes.RemoveAttachFromTopicSubmit,
"routes.ViewTopic": routes.ViewTopic,
"routes.CreateReplySubmit": routes.CreateReplySubmit,
"routes.ReplyEditSubmit": routes.ReplyEditSubmit,
"routes.ReplyDeleteSubmit": routes.ReplyDeleteSubmit,
"routes.ReplyLikeSubmit": routes.ReplyLikeSubmit,
"routes.AddAttachToReplySubmit": routes.AddAttachToReplySubmit,
"routes.RemoveAttachFromReplySubmit": routes.RemoveAttachFromReplySubmit,
"routes.ProfileReplyCreateSubmit": routes.ProfileReplyCreateSubmit,
"routes.ProfileReplyEditSubmit": routes.ProfileReplyEditSubmit,
"routes.ProfileReplyDeleteSubmit": routes.ProfileReplyDeleteSubmit,
"routes.PollVote": routes.PollVote,
"routes.PollResults": routes.PollResults,
"routes.AccountLogin": routes.AccountLogin,
"routes.AccountRegister": routes.AccountRegister,
"routes.AccountLogout": routes.AccountLogout,
"routes.AccountLoginSubmit": routes.AccountLoginSubmit,
"routes.AccountLoginMFAVerify": routes.AccountLoginMFAVerify,
"routes.AccountLoginMFAVerifySubmit": routes.AccountLoginMFAVerifySubmit,
"routes.AccountRegisterSubmit": routes.AccountRegisterSubmit,
"routes.AccountPasswordReset": routes.AccountPasswordReset,
"routes.AccountPasswordResetSubmit": routes.AccountPasswordResetSubmit,
"routes.AccountPasswordResetToken": routes.AccountPasswordResetToken,
"routes.AccountPasswordResetTokenSubmit": routes.AccountPasswordResetTokenSubmit,
"routes.DynamicRoute": routes.DynamicRoute,
"routes.UploadedFile": routes.UploadedFile,
"routes.StaticFile": routes.StaticFile,
"routes.RobotsTxt": routes.RobotsTxt,
"routes.SitemapXml": routes.SitemapXml,
"routes.BadRoute": routes.BadRoute,
}
// ! NEVER RELY ON THESE REMAINING THE SAME BETWEEN COMMITS
var routeMapEnum = map[string]int{
"routes.Overview": 0,
"routes.CustomPage": 1,
"routes.ForumList": 2,
"routes.ViewForum": 3,
"routes.ChangeTheme": 4,
"routes.ShowAttachment": 5,
"common.RouteWebsockets": 6,
"routeAPIPhrases": 7,
"routes.APIMe": 8,
"routeJSAntispam": 9,
"routeAPI": 10,
"routes.ReportSubmit": 11,
"routes.TopicListMostViewed": 12,
"routes.CreateTopic": 13,
"routes.TopicList": 14,
"panel.Forums": 15,
"panel.ForumsCreateSubmit": 16,
"panel.ForumsDelete": 17,
"panel.ForumsDeleteSubmit": 18,
"panel.ForumsEdit": 19,
"panel.ForumsEditSubmit": 20,
"panel.ForumsEditPermsSubmit": 21,
"panel.ForumsEditPermsAdvance": 22,
"panel.ForumsEditPermsAdvanceSubmit": 23,
"panel.Settings": 24,
"panel.SettingEdit": 25,
"panel.SettingEditSubmit": 26,
"panel.WordFilters": 27,
"panel.WordFiltersCreateSubmit": 28,
"panel.WordFiltersEdit": 29,
"panel.WordFiltersEditSubmit": 30,
"panel.WordFiltersDeleteSubmit": 31,
"panel.Pages": 32,
"panel.PagesCreateSubmit": 33,
"panel.PagesEdit": 34,
"panel.PagesEditSubmit": 35,
"panel.PagesDeleteSubmit": 36,
"panel.Themes": 37,
"panel.ThemesSetDefault": 38,
"panel.ThemesMenus": 39,
"panel.ThemesMenusEdit": 40,
"panel.ThemesMenuItemEdit": 41,
"panel.ThemesMenuItemEditSubmit": 42,
"panel.ThemesMenuItemCreateSubmit": 43,
"panel.ThemesMenuItemDeleteSubmit": 44,
"panel.ThemesMenuItemOrderSubmit": 45,
"panel.ThemesWidgets": 46,
"panel.ThemesWidgetsEditSubmit": 47,
"panel.ThemesWidgetsCreateSubmit": 48,
"panel.ThemesWidgetsDeleteSubmit": 49,
"panel.Plugins": 50,
"panel.PluginsActivate": 51,
"panel.PluginsDeactivate": 52,
"panel.PluginsInstall": 53,
"panel.Users": 54,
"panel.UsersEdit": 55,
"panel.UsersEditSubmit": 56,
"panel.AnalyticsViews": 57,
"panel.AnalyticsRoutes": 58,
"panel.AnalyticsAgents": 59,
"panel.AnalyticsSystems": 60,
"panel.AnalyticsLanguages": 61,
"panel.AnalyticsReferrers": 62,
"panel.AnalyticsRouteViews": 63,
"panel.AnalyticsAgentViews": 64,
"panel.AnalyticsForumViews": 65,
"panel.AnalyticsSystemViews": 66,
"panel.AnalyticsLanguageViews": 67,
"panel.AnalyticsReferrerViews": 68,
"panel.AnalyticsPosts": 69,
"panel.AnalyticsTopics": 70,
"panel.AnalyticsForums": 71,
"panel.Groups": 72,
"panel.GroupsEdit": 73,
"panel.GroupsEditPerms": 74,
"panel.GroupsEditSubmit": 75,
"panel.GroupsEditPermsSubmit": 76,
"panel.GroupsCreateSubmit": 77,
"panel.Backups": 78,
"panel.LogsRegs": 79,
"panel.LogsMod": 80,
"panel.Debug": 81,
"panel.Dashboard": 82,
"routes.AccountEdit": 83,
"routes.AccountEditPassword": 84,
"routes.AccountEditPasswordSubmit": 85,
"routes.AccountEditAvatarSubmit": 86,
"routes.AccountEditUsernameSubmit": 87,
"routes.AccountEditMFA": 88,
"routes.AccountEditMFASetup": 89,
"routes.AccountEditMFASetupSubmit": 90,
"routes.AccountEditMFADisableSubmit": 91,
"routes.AccountEditEmail": 92,
"routes.AccountEditEmailTokenSubmit": 93,
"routes.AccountLogins": 94,
"routes.LevelList": 95,
"routes.ViewProfile": 96,
"routes.BanUserSubmit": 97,
"routes.UnbanUser": 98,
"routes.ActivateUser": 99,
"routes.IPSearch": 100,
"routes.CreateTopicSubmit": 101,
"routes.EditTopicSubmit": 102,
"routes.DeleteTopicSubmit": 103,
"routes.StickTopicSubmit": 104,
"routes.UnstickTopicSubmit": 105,
"routes.LockTopicSubmit": 106,
"routes.UnlockTopicSubmit": 107,
"routes.MoveTopicSubmit": 108,
"routes.LikeTopicSubmit": 109,
"routes.AddAttachToTopicSubmit": 110,
"routes.RemoveAttachFromTopicSubmit": 111,
"routes.ViewTopic": 112,
"routes.CreateReplySubmit": 113,
"routes.ReplyEditSubmit": 114,
"routes.ReplyDeleteSubmit": 115,
"routes.ReplyLikeSubmit": 116,
"routes.AddAttachToReplySubmit": 117,
"routes.RemoveAttachFromReplySubmit": 118,
"routes.ProfileReplyCreateSubmit": 119,
"routes.ProfileReplyEditSubmit": 120,
"routes.ProfileReplyDeleteSubmit": 121,
"routes.PollVote": 122,
"routes.PollResults": 123,
"routes.AccountLogin": 124,
"routes.AccountRegister": 125,
"routes.AccountLogout": 126,
"routes.AccountLoginSubmit": 127,
"routes.AccountLoginMFAVerify": 128,
"routes.AccountLoginMFAVerifySubmit": 129,
"routes.AccountRegisterSubmit": 130,
"routes.AccountPasswordReset": 131,
"routes.AccountPasswordResetSubmit": 132,
"routes.AccountPasswordResetToken": 133,
"routes.AccountPasswordResetTokenSubmit": 134,
"routes.DynamicRoute": 135,
"routes.UploadedFile": 136,
"routes.StaticFile": 137,
"routes.RobotsTxt": 138,
"routes.SitemapXml": 139,
"routes.BadRoute": 140,
}
var reverseRouteMapEnum = map[int]string{
0: "routes.Overview",
1: "routes.CustomPage",
2: "routes.ForumList",
3: "routes.ViewForum",
4: "routes.ChangeTheme",
5: "routes.ShowAttachment",
6: "common.RouteWebsockets",
7: "routeAPIPhrases",
8: "routes.APIMe",
9: "routeJSAntispam",
10: "routeAPI",
11: "routes.ReportSubmit",
12: "routes.TopicListMostViewed",
13: "routes.CreateTopic",
14: "routes.TopicList",
15: "panel.Forums",
16: "panel.ForumsCreateSubmit",
17: "panel.ForumsDelete",
18: "panel.ForumsDeleteSubmit",
19: "panel.ForumsEdit",
20: "panel.ForumsEditSubmit",
21: "panel.ForumsEditPermsSubmit",
22: "panel.ForumsEditPermsAdvance",
23: "panel.ForumsEditPermsAdvanceSubmit",
24: "panel.Settings",
25: "panel.SettingEdit",
26: "panel.SettingEditSubmit",
27: "panel.WordFilters",
28: "panel.WordFiltersCreateSubmit",
29: "panel.WordFiltersEdit",
30: "panel.WordFiltersEditSubmit",
31: "panel.WordFiltersDeleteSubmit",
32: "panel.Pages",
33: "panel.PagesCreateSubmit",
34: "panel.PagesEdit",
35: "panel.PagesEditSubmit",
36: "panel.PagesDeleteSubmit",
37: "panel.Themes",
38: "panel.ThemesSetDefault",
39: "panel.ThemesMenus",
40: "panel.ThemesMenusEdit",
41: "panel.ThemesMenuItemEdit",
42: "panel.ThemesMenuItemEditSubmit",
43: "panel.ThemesMenuItemCreateSubmit",
44: "panel.ThemesMenuItemDeleteSubmit",
45: "panel.ThemesMenuItemOrderSubmit",
46: "panel.ThemesWidgets",
47: "panel.ThemesWidgetsEditSubmit",
48: "panel.ThemesWidgetsCreateSubmit",
49: "panel.ThemesWidgetsDeleteSubmit",
50: "panel.Plugins",
51: "panel.PluginsActivate",
52: "panel.PluginsDeactivate",
53: "panel.PluginsInstall",
54: "panel.Users",
55: "panel.UsersEdit",
56: "panel.UsersEditSubmit",
57: "panel.AnalyticsViews",
58: "panel.AnalyticsRoutes",
59: "panel.AnalyticsAgents",
60: "panel.AnalyticsSystems",
61: "panel.AnalyticsLanguages",
62: "panel.AnalyticsReferrers",
63: "panel.AnalyticsRouteViews",
64: "panel.AnalyticsAgentViews",
65: "panel.AnalyticsForumViews",
66: "panel.AnalyticsSystemViews",
67: "panel.AnalyticsLanguageViews",
68: "panel.AnalyticsReferrerViews",
69: "panel.AnalyticsPosts",
70: "panel.AnalyticsTopics",
71: "panel.AnalyticsForums",
72: "panel.Groups",
73: "panel.GroupsEdit",
74: "panel.GroupsEditPerms",
75: "panel.GroupsEditSubmit",
76: "panel.GroupsEditPermsSubmit",
77: "panel.GroupsCreateSubmit",
78: "panel.Backups",
79: "panel.LogsRegs",
80: "panel.LogsMod",
81: "panel.Debug",
82: "panel.Dashboard",
83: "routes.AccountEdit",
84: "routes.AccountEditPassword",
85: "routes.AccountEditPasswordSubmit",
86: "routes.AccountEditAvatarSubmit",
87: "routes.AccountEditUsernameSubmit",
88: "routes.AccountEditMFA",
89: "routes.AccountEditMFASetup",
90: "routes.AccountEditMFASetupSubmit",
91: "routes.AccountEditMFADisableSubmit",
92: "routes.AccountEditEmail",
93: "routes.AccountEditEmailTokenSubmit",
94: "routes.AccountLogins",
95: "routes.LevelList",
96: "routes.ViewProfile",
97: "routes.BanUserSubmit",
98: "routes.UnbanUser",
99: "routes.ActivateUser",
100: "routes.IPSearch",
101: "routes.CreateTopicSubmit",
102: "routes.EditTopicSubmit",
103: "routes.DeleteTopicSubmit",
104: "routes.StickTopicSubmit",
105: "routes.UnstickTopicSubmit",
106: "routes.LockTopicSubmit",
107: "routes.UnlockTopicSubmit",
108: "routes.MoveTopicSubmit",
109: "routes.LikeTopicSubmit",
110: "routes.AddAttachToTopicSubmit",
111: "routes.RemoveAttachFromTopicSubmit",
112: "routes.ViewTopic",
113: "routes.CreateReplySubmit",
114: "routes.ReplyEditSubmit",
115: "routes.ReplyDeleteSubmit",
116: "routes.ReplyLikeSubmit",
117: "routes.AddAttachToReplySubmit",
118: "routes.RemoveAttachFromReplySubmit",
119: "routes.ProfileReplyCreateSubmit",
120: "routes.ProfileReplyEditSubmit",
121: "routes.ProfileReplyDeleteSubmit",
122: "routes.PollVote",
123: "routes.PollResults",
124: "routes.AccountLogin",
125: "routes.AccountRegister",
126: "routes.AccountLogout",
127: "routes.AccountLoginSubmit",
128: "routes.AccountLoginMFAVerify",
129: "routes.AccountLoginMFAVerifySubmit",
130: "routes.AccountRegisterSubmit",
131: "routes.AccountPasswordReset",
132: "routes.AccountPasswordResetSubmit",
133: "routes.AccountPasswordResetToken",
134: "routes.AccountPasswordResetTokenSubmit",
135: "routes.DynamicRoute",
136: "routes.UploadedFile",
137: "routes.StaticFile",
138: "routes.RobotsTxt",
139: "routes.SitemapXml",
140: "routes.BadRoute",
}
var osMapEnum = map[string]int{
"unknown": 0,
"windows": 1,
"linux": 2,
"mac": 3,
"android": 4,
"iphone": 5,
}
var reverseOSMapEnum = map[int]string{
0: "unknown",
1: "windows",
2: "linux",
3: "mac",
4: "android",
5: "iphone",
}
var agentMapEnum = map[string]int{
"unknown": 0,
"firefox": 1,
"chrome": 2,
"opera": 3,
"safari": 4,
"edge": 5,
"internetexplorer": 6,
"trident": 7,
"androidchrome": 8,
"mobilesafari": 9,
"samsung": 10,
"ucbrowser": 11,
"googlebot": 12,
"yandex": 13,
"bing": 14,
"baidu": 15,
"duckduckgo": 16,
"seznambot": 17,
"discord": 18,
"twitter": 19,
"facebook": 20,
"cloudflare": 21,
"uptimebot": 22,
"slackbot": 23,
"discourse": 24,
"lynx": 25,
"blank": 26,
"malformed": 27,
"suspicious": 28,
"semrush": 29,
"dotbot": 30,
"zgrab": 31,
}
var reverseAgentMapEnum = map[int]string{
0: "unknown",
1: "firefox",
2: "chrome",
3: "opera",
4: "safari",
5: "edge",
6: "internetexplorer",
7: "trident",
8: "androidchrome",
9: "mobilesafari",
10: "samsung",
11: "ucbrowser",
12: "googlebot",
13: "yandex",
14: "bing",
15: "baidu",
16: "duckduckgo",
17: "seznambot",
18: "discord",
19: "twitter",
20: "facebook",
21: "cloudflare",
22: "uptimebot",
23: "slackbot",
24: "discourse",
25: "lynx",
26: "blank",
27: "malformed",
28: "suspicious",
29: "semrush",
30: "dotbot",
31: "zgrab",
}
var markToAgent = map[string]string{
"OPR": "opera",
"Chrome": "chrome",
"Firefox": "firefox",
"MSIE": "internetexplorer",
"Trident": "trident",
"Edge": "edge",
"Lynx": "lynx",
"SamsungBrowser": "samsung",
"UCBrowser": "ucbrowser",
"Google": "googlebot",
"Googlebot": "googlebot",
"yandex": "yandex",
"DuckDuckBot": "duckduckgo",
"Baiduspider": "baidu",
"bingbot": "bing",
"BingPreview": "bing",
"SeznamBot": "seznambot",
"CloudFlare": "cloudflare",
"Uptimebot": "uptimebot",
"Slackbot": "slackbot",
"Discordbot": "discord",
"Twitterbot": "twitter",
"facebookexternalhit": "facebook",
"Facebot": "facebook",
"Discourse": "discourse",
"SemrushBot": "semrush",
"DotBot": "dotbot",
"zgrab": "zgrab",
}
/*var agentRank = map[string]int{
"opera":9,
"chrome":8,
"safari":1,
}*/
// TODO: Stop spilling these into the package scope?
func init() {
counters.SetRouteMapEnum(routeMapEnum)
counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
counters.SetAgentMapEnum(agentMapEnum)
counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
counters.SetOSMapEnum(osMapEnum)
counters.SetReverseOSMapEnum(reverseOSMapEnum)
}
type WriterIntercept struct {
http.ResponseWriter
}
func NewWriterIntercept(w http.ResponseWriter) *WriterIntercept {
return &WriterIntercept{w}
}
var wiMaxAge = "max-age=" + strconv.Itoa(int(common.Day))
func (writ *WriterIntercept) WriteHeader(code int) {
if code == 200 {
writ.ResponseWriter.Header().Set("Cache-Control", wiMaxAge)
writ.ResponseWriter.Header().Set("Vary", "Accept-Encoding")
}
writ.ResponseWriter.WriteHeader(code)
}
type GenRouter struct {
UploadHandler func(http.ResponseWriter, *http.Request)
extraRoutes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
requestLogger *log.Logger
sync.RWMutex
}
func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
f, err := os.OpenFile("./logs/reqs-"+strconv.FormatInt(common.StartTime.Unix(),10)+".log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
return nil, err
}
return &GenRouter{
UploadHandler: func(w http.ResponseWriter, req *http.Request) {
writ := NewWriterIntercept(w)
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
},
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
requestLogger: log.New(f, "", log.LstdFlags),
}, nil
}
func (r *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, req *http.Request, user common.User) {
if err.Handled() {
return
}
if err.Type() == "system" {
common.InternalErrorJSQ(err, w, req, err.JSON())
return
}
common.LocalErrorJSQ(err.Error(), w, req, user, err.JSON())
}
func (r *GenRouter) Handle(_ string, _ http.Handler) {
}
func (r *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, common.User) common.RouteError) {
r.Lock()
defer r.Unlock()
r.extraRoutes[pattern] = handle
}
func (r *GenRouter) RemoveFunc(pattern string) error {
r.Lock()
defer r.Unlock()
_, ok := r.extraRoutes[pattern]
if !ok {
return ErrNoRoute
}
delete(r.extraRoutes, pattern)
return nil
}
func (r *GenRouter) DumpRequest(req *http.Request, prepend string) {
var heads string
for key, value := range req.Header {
for _, vvalue := range value {
heads += "Header '" + common.SanitiseSingleLine(key) + "': " + common.SanitiseSingleLine(vvalue) + "!\n"
}
}
r.requestLogger.Print(prepend +
"\nUA: " + common.SanitiseSingleLine(req.UserAgent()) + "\n" +
"Method: " + common.SanitiseSingleLine(req.Method) + "\n" + heads +
"req.Host: " + common.SanitiseSingleLine(req.Host) + "\n" +
"req.URL.Path: " + common.SanitiseSingleLine(req.URL.Path) + "\n" +
"req.URL.RawQuery: " + common.SanitiseSingleLine(req.URL.RawQuery) + "\n" +
"req.Referer(): " + common.SanitiseSingleLine(req.Referer()) + "\n" +
"req.RemoteAddr: " + req.RemoteAddr + "\n")
}
func (r *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
if prepend != "" {
prepend += "\n"
}
r.DumpRequest(req,prepend+"Suspicious Request")
counters.AgentViewCounter.Bump(28)
}
// TODO: Pass the default path or config struct to the router rather than accessing it via a package global
// TODO: SetDefaultPath
// TODO: GetDefaultPath
func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Redirect www. requests to the right place
if req.Host == "www." + common.Site.Host {
w.Header().Set("Connection", "close")
var s string
if common.Site.EnableSsl {
s = "s"
}
dest := "http"+s+"://" + common.Site.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
dest += "?" + req.URL.RawQuery
}
http.Redirect(w, req, dest, http.StatusMovedPermanently)
return
}
// Deflect malformed requests
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || req.Host != common.Site.Host {
w.WriteHeader(200) // 400
w.Write([]byte(""))
r.DumpRequest(req,"Malformed Request")
counters.AgentViewCounter.Bump(27)
return
}
// TODO: Cover more suspicious strings and at a lower layer than this
for _, char := range req.URL.Path {
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
r.SuspiciousRequest(req,"Bad char in path")
break
}
}
lowerPath := strings.ToLower(req.URL.Path)
// TODO: Flag any requests which has a dot with anything but a number after that
if strings.Contains(req.URL.Path,"..") || strings.Contains(req.URL.Path,"--") || strings.Contains(lowerPath,".php") || strings.Contains(lowerPath,".asp") || strings.Contains(lowerPath,".cgi") || strings.Contains(lowerPath,".py") || strings.Contains(lowerPath,".sql") || strings.Contains(lowerPath,".action") {
r.SuspiciousRequest(req,"Bad snippet in path")
}
// Indirect the default route onto a different one
if req.URL.Path == "/" {
req.URL.Path = common.Config.DefaultPath
}
var prefix, extraData string
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1]
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 prefix != "/ws" {
h := w.Header()
h.Set("X-Frame-Options", "deny")
h.Set("X-XSS-Protection", "1; mode=block") // TODO: Remove when we add a CSP? CSP's are horrendously glitchy things, tread with caution before removing
// TODO: Set the content policy header
h.Set("X-Content-Type-Options", "nosniff")
}
if common.Dev.SuperDebug {
r.DumpRequest(req,"before routes.StaticFile")
}
// Increment the request counter
counters.GlobalViewCounter.Bump()
if prefix == "/static" {
counters.RouteViewCounter.Bump(137)
req.URL.Path += extraData
routes.StaticFile(w, req)
return
}
if atomic.LoadInt32(&common.IsDBDown) == 1 {
common.DatabaseError(w, req)
return
}
if common.Dev.SuperDebug {
r.requestLogger.Print("before PreRoute")
}
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
// TODO: Add a setting to disable this?
// TODO: Use a more efficient detector instead of smashing every possible combination in
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
if ua == "" {
counters.AgentViewCounter.Bump(26)
if common.Dev.DebugMode {
var prepend string
for _, char := range req.UserAgent() {
prepend += strconv.Itoa(int(char)) + " "
}
r.DumpRequest(req,"Blank UA: " + prepend)
}
} else {
// WIP UA Parser
var items []string
var buffer []byte
var os string
for _, item := range StringToBytes(ua) {
if (item > 64 && item < 91) || (item > 96 && item < 123) {
buffer = append(buffer, item)
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == ':' || item == '.' || item == '+' || item == '~' || item == '@' || (item == ':' && bytes.Equal(buffer,[]byte("http"))) || item == ',' || item == '/' {
if len(buffer) != 0 {
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
switch(BytesToString(buffer)) {
case "Windows":
os = "windows"
case "Linux":
os = "linux"
case "Mac":
os = "mac"
case "iPhone":
os = "iphone"
case "Android":
os = "android"
case "like","compatible":
// Skip these words
default:
items = append(items, string(buffer))
}
}
buffer = buffer[:0]
}
} else {
// TODO: Test this
items = items[:0]
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(item))+" in UA")
r.requestLogger.Print("UA Buffer: ", buffer)
r.requestLogger.Print("UA Buffer String: ", string(buffer))
break
}
}
if os == "" {
os = "unknown"
}
// Iterate over this in reverse as the real UA tends to be on the right side
var agent string
for i := len(items) - 1; i >= 0; i-- {
fAgent, ok := markToAgent[items[i]]
if ok {
agent = fAgent
if agent != "safari" {
break
}
}
}
if common.Dev.SuperDebug {
r.requestLogger.Print("parsed agent: ", agent)
}
if common.Dev.SuperDebug {
r.requestLogger.Print("os: ", os)
r.requestLogger.Printf("items: %+v\n",items)
}
// Special handling
switch(agent) {
case "chrome":
if os == "android" {
agent = "androidchrome"
}
case "safari":
if os == "iphone" {
agent = "mobilesafari"
}
case "trident":
// Hack to support IE11, change this after we start logging versions
if strings.Contains(ua,"rv:11") {
agent = "internetexplorer"
}
case "zgrab":
r.SuspiciousRequest(req,"Vulnerability Scanner")
}
if agent == "" {
counters.AgentViewCounter.Bump(0)
if common.Dev.DebugMode {
var prepend string
for _, char := range req.UserAgent() {
prepend += strconv.Itoa(int(char)) + " "
}
r.DumpRequest(req,"Blank UA: " + prepend)
}
} else {
counters.AgentViewCounter.Bump(agentMapEnum[agent])
}
counters.OSViewCounter.Bump(osMapEnum[os])
}
// TODO: Do we want to track missing language headers too? Maybe as it's own type, e.g. "noheader"?
lang := req.Header.Get("Accept-Language")
if lang != "" {
lang = strings.TrimSpace(lang)
lLang := strings.Split(lang,"-")
tLang := strings.Split(strings.Split(lLang[0],";")[0],",")
common.DebugDetail("tLang:", tLang)
var llLang string
for _, seg := range tLang {
if seg == "*" {
continue
}
llLang = seg
break
}
common.DebugDetail("llLang:", llLang)
if llLang == "" {
counters.LangViewCounter.Bump("none")
} else {
validCode := counters.LangViewCounter.Bump(llLang)
if !validCode {
r.DumpRequest(req,"Invalid ISO Code")
}
}
} else {
counters.LangViewCounter.Bump("none")
}
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
if referrer != "" {
// ? Optimise this a little?
referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
referrer = strings.Split(referrer,"/")[0]
portless := strings.Split(referrer,":")[0]
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
counters.ReferrerTracker.Bump(referrer)
}
}
// Deal with the session stuff, etc.
user, ok := common.PreRoute(w, req)
if !ok {
return
}
if common.Dev.SuperDebug {
r.requestLogger.Print(
"after PreRoute\n" +
"routeMapEnum: ", routeMapEnum)
}
// Disable Gzip when SSL is disabled for security reasons?
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
w.Header().Set("Content-Encoding", "gzip")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
gz := gzip.NewWriter(w)
defer func() {
if w.Header().Get("Content-Encoding") == "gzip" {
gz.Close()
}
}()
w = common.GzipResponseWriter{Writer: gz, ResponseWriter: w}
}
ferr := r.routeSwitch(w, req, user, prefix, extraData)
if ferr != nil {
r.handleError(ferr,w,req,user)
}
//common.StoppedServer("Profile end")
}
func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user common.User, prefix string, extraData string) common.RouteError {
var err common.RouteError
switch(prefix) {
case "/overview":
counters.RouteViewCounter.Bump(0)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.Overview(w,req,user,head)
case "/pages":
counters.RouteViewCounter.Bump(1)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.CustomPage(w,req,user,head,extraData)
case "/forums":
counters.RouteViewCounter.Bump(2)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.ForumList(w,req,user,head)
case "/forum":
counters.RouteViewCounter.Bump(3)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.ViewForum(w,req,user,head,extraData)
case "/theme":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(4)
err = routes.ChangeTheme(w,req,user)
case "/attachs":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
gzw, ok := w.(common.GzipResponseWriter)
if ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Type")
w.Header().Del("Content-Encoding")
}
counters.RouteViewCounter.Bump(5)
err = routes.ShowAttachment(w,req,user,extraData)
case "/ws":
req.URL.Path += extraData
counters.RouteViewCounter.Bump(6)
err = common.RouteWebsockets(w,req,user)
case "/api":
switch(req.URL.Path) {
case "/api/phrases/":
counters.RouteViewCounter.Bump(7)
err = routeAPIPhrases(w,req,user)
case "/api/me/":
counters.RouteViewCounter.Bump(8)
err = routes.APIMe(w,req,user)
case "/api/watches/":
counters.RouteViewCounter.Bump(9)
err = routeJSAntispam(w,req,user)
default:
counters.RouteViewCounter.Bump(10)
err = routeAPI(w,req,user)
}
case "/report":
err = common.NoBanned(w,req,user)
if err != nil {
return err
}
switch(req.URL.Path) {
case "/report/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(11)
err = routes.ReportSubmit(w,req,user,extraData)
}
case "/topics":
switch(req.URL.Path) {
case "/topics/most-viewed/":
counters.RouteViewCounter.Bump(12)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.TopicListMostViewed(w,req,user,head)
case "/topics/create/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(13)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.CreateTopic(w,req,user,head,extraData)
default:
counters.RouteViewCounter.Bump(14)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.TopicList(w,req,user, head)
}
case "/panel":
err = common.SuperModOnly(w,req,user)
if err != nil {
return err
}
switch(req.URL.Path) {
case "/panel/forums/":
counters.RouteViewCounter.Bump(15)
err = panel.Forums(w,req,user)
case "/panel/forums/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(16)
err = panel.ForumsCreateSubmit(w,req,user)
case "/panel/forums/delete/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(17)
err = panel.ForumsDelete(w,req,user,extraData)
case "/panel/forums/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(18)
err = panel.ForumsDeleteSubmit(w,req,user,extraData)
case "/panel/forums/edit/":
counters.RouteViewCounter.Bump(19)
err = panel.ForumsEdit(w,req,user,extraData)
case "/panel/forums/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(20)
err = panel.ForumsEditSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(21)
err = panel.ForumsEditPermsSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/":
counters.RouteViewCounter.Bump(22)
err = panel.ForumsEditPermsAdvance(w,req,user,extraData)
case "/panel/forums/edit/perms/adv/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(23)
err = panel.ForumsEditPermsAdvanceSubmit(w,req,user,extraData)
case "/panel/settings/":
counters.RouteViewCounter.Bump(24)
err = panel.Settings(w,req,user)
case "/panel/settings/edit/":
counters.RouteViewCounter.Bump(25)
err = panel.SettingEdit(w,req,user,extraData)
case "/panel/settings/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(26)
err = panel.SettingEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/":
counters.RouteViewCounter.Bump(27)
err = panel.WordFilters(w,req,user)
case "/panel/settings/word-filters/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(28)
err = panel.WordFiltersCreateSubmit(w,req,user)
case "/panel/settings/word-filters/edit/":
counters.RouteViewCounter.Bump(29)
err = panel.WordFiltersEdit(w,req,user,extraData)
case "/panel/settings/word-filters/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(30)
err = panel.WordFiltersEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(31)
err = panel.WordFiltersDeleteSubmit(w,req,user,extraData)
case "/panel/pages/":
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(32)
err = panel.Pages(w,req,user)
case "/panel/pages/create/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(33)
err = panel.PagesCreateSubmit(w,req,user)
case "/panel/pages/edit/":
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(34)
err = panel.PagesEdit(w,req,user,extraData)
case "/panel/pages/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(35)
err = panel.PagesEditSubmit(w,req,user,extraData)
case "/panel/pages/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(36)
err = panel.PagesDeleteSubmit(w,req,user,extraData)
case "/panel/themes/":
counters.RouteViewCounter.Bump(37)
err = panel.Themes(w,req,user)
case "/panel/themes/default/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(38)
err = panel.ThemesSetDefault(w,req,user,extraData)
case "/panel/themes/menus/":
counters.RouteViewCounter.Bump(39)
err = panel.ThemesMenus(w,req,user)
case "/panel/themes/menus/edit/":
counters.RouteViewCounter.Bump(40)
err = panel.ThemesMenusEdit(w,req,user,extraData)
case "/panel/themes/menus/item/edit/":
counters.RouteViewCounter.Bump(41)
err = panel.ThemesMenuItemEdit(w,req,user,extraData)
case "/panel/themes/menus/item/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(42)
err = panel.ThemesMenuItemEditSubmit(w,req,user,extraData)
case "/panel/themes/menus/item/create/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(43)
err = panel.ThemesMenuItemCreateSubmit(w,req,user)
case "/panel/themes/menus/item/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(44)
err = panel.ThemesMenuItemDeleteSubmit(w,req,user,extraData)
case "/panel/themes/menus/item/order/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(45)
err = panel.ThemesMenuItemOrderSubmit(w,req,user,extraData)
case "/panel/themes/widgets/":
counters.RouteViewCounter.Bump(46)
err = panel.ThemesWidgets(w,req,user)
case "/panel/themes/widgets/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(47)
err = panel.ThemesWidgetsEditSubmit(w,req,user,extraData)
case "/panel/themes/widgets/create/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(48)
err = panel.ThemesWidgetsCreateSubmit(w,req,user)
case "/panel/themes/widgets/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(49)
err = panel.ThemesWidgetsDeleteSubmit(w,req,user,extraData)
case "/panel/plugins/":
counters.RouteViewCounter.Bump(50)
err = panel.Plugins(w,req,user)
case "/panel/plugins/activate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(51)
err = panel.PluginsActivate(w,req,user,extraData)
case "/panel/plugins/deactivate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(52)
err = panel.PluginsDeactivate(w,req,user,extraData)
case "/panel/plugins/install/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(53)
err = panel.PluginsInstall(w,req,user,extraData)
case "/panel/users/":
counters.RouteViewCounter.Bump(54)
err = panel.Users(w,req,user)
case "/panel/users/edit/":
counters.RouteViewCounter.Bump(55)
err = panel.UsersEdit(w,req,user,extraData)
case "/panel/users/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(56)
err = panel.UsersEditSubmit(w,req,user,extraData)
case "/panel/analytics/views/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(57)
err = panel.AnalyticsViews(w,req,user)
case "/panel/analytics/routes/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(58)
err = panel.AnalyticsRoutes(w,req,user)
case "/panel/analytics/agents/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(59)
err = panel.AnalyticsAgents(w,req,user)
case "/panel/analytics/systems/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(60)
err = panel.AnalyticsSystems(w,req,user)
case "/panel/analytics/langs/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(61)
err = panel.AnalyticsLanguages(w,req,user)
case "/panel/analytics/referrers/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(62)
err = panel.AnalyticsReferrers(w,req,user)
case "/panel/analytics/route/":
counters.RouteViewCounter.Bump(63)
err = panel.AnalyticsRouteViews(w,req,user,extraData)
case "/panel/analytics/agent/":
counters.RouteViewCounter.Bump(64)
err = panel.AnalyticsAgentViews(w,req,user,extraData)
case "/panel/analytics/forum/":
counters.RouteViewCounter.Bump(65)
err = panel.AnalyticsForumViews(w,req,user,extraData)
case "/panel/analytics/system/":
counters.RouteViewCounter.Bump(66)
err = panel.AnalyticsSystemViews(w,req,user,extraData)
case "/panel/analytics/lang/":
counters.RouteViewCounter.Bump(67)
err = panel.AnalyticsLanguageViews(w,req,user,extraData)
case "/panel/analytics/referrer/":
counters.RouteViewCounter.Bump(68)
err = panel.AnalyticsReferrerViews(w,req,user,extraData)
case "/panel/analytics/posts/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(69)
err = panel.AnalyticsPosts(w,req,user)
case "/panel/analytics/topics/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(70)
err = panel.AnalyticsTopics(w,req,user)
case "/panel/analytics/forums/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(71)
err = panel.AnalyticsForums(w,req,user)
case "/panel/groups/":
counters.RouteViewCounter.Bump(72)
err = panel.Groups(w,req,user)
case "/panel/groups/edit/":
counters.RouteViewCounter.Bump(73)
err = panel.GroupsEdit(w,req,user,extraData)
case "/panel/groups/edit/perms/":
counters.RouteViewCounter.Bump(74)
err = panel.GroupsEditPerms(w,req,user,extraData)
case "/panel/groups/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(75)
err = panel.GroupsEditSubmit(w,req,user,extraData)
case "/panel/groups/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(76)
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
case "/panel/groups/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(77)
err = panel.GroupsCreateSubmit(w,req,user)
case "/panel/backups/":
err = common.SuperAdminOnly(w,req,user)
if err != nil {
return err
}
gzw, ok := w.(common.GzipResponseWriter)
if ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Type")
w.Header().Del("Content-Encoding")
}
counters.RouteViewCounter.Bump(78)
err = panel.Backups(w,req,user,extraData)
case "/panel/logs/regs/":
counters.RouteViewCounter.Bump(79)
err = panel.LogsRegs(w,req,user)
case "/panel/logs/mod/":
counters.RouteViewCounter.Bump(80)
err = panel.LogsMod(w,req,user)
case "/panel/debug/":
err = common.AdminOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(81)
err = panel.Debug(w,req,user)
default:
counters.RouteViewCounter.Bump(82)
err = panel.Dashboard(w,req,user)
}
case "/user":
switch(req.URL.Path) {
case "/user/edit/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(83)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountEdit(w,req,user,head)
case "/user/edit/password/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(84)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountEditPassword(w,req,user,head)
case "/user/edit/password/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(85)
err = routes.AccountEditPasswordSubmit(w,req,user)
case "/user/edit/avatar/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
return err
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(86)
err = routes.AccountEditAvatarSubmit(w,req,user)
case "/user/edit/username/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(87)
err = routes.AccountEditUsernameSubmit(w,req,user)
case "/user/edit/mfa/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(88)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountEditMFA(w,req,user,head)
case "/user/edit/mfa/setup/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(89)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountEditMFASetup(w,req,user,head)
case "/user/edit/mfa/setup/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(90)
err = routes.AccountEditMFASetupSubmit(w,req,user)
case "/user/edit/mfa/disable/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(91)
err = routes.AccountEditMFADisableSubmit(w,req,user)
case "/user/edit/email/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(92)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountEditEmail(w,req,user,head)
case "/user/edit/token/":
counters.RouteViewCounter.Bump(93)
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
case "/user/edit/logins/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(94)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountLogins(w,req,user,head)
case "/user/levels/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(95)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.LevelList(w,req,user,head)
default:
req.URL.Path += extraData
counters.RouteViewCounter.Bump(96)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.ViewProfile(w,req,user, head)
}
case "/users":
switch(req.URL.Path) {
case "/users/ban/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(97)
err = routes.BanUserSubmit(w,req,user,extraData)
case "/users/unban/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(98)
err = routes.UnbanUser(w,req,user,extraData)
case "/users/activate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(99)
err = routes.ActivateUser(w,req,user,extraData)
case "/users/ips/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(100)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.IPSearch(w,req,user,head)
}
case "/topic":
switch(req.URL.Path) {
case "/topic/create/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
return err
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(101)
err = routes.CreateTopicSubmit(w,req,user)
case "/topic/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(102)
err = routes.EditTopicSubmit(w,req,user,extraData)
case "/topic/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
req.URL.Path += extraData
counters.RouteViewCounter.Bump(103)
err = routes.DeleteTopicSubmit(w,req,user)
case "/topic/stick/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(104)
err = routes.StickTopicSubmit(w,req,user,extraData)
case "/topic/unstick/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(105)
err = routes.UnstickTopicSubmit(w,req,user,extraData)
case "/topic/lock/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
req.URL.Path += extraData
counters.RouteViewCounter.Bump(106)
err = routes.LockTopicSubmit(w,req,user)
case "/topic/unlock/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(107)
err = routes.UnlockTopicSubmit(w,req,user,extraData)
case "/topic/move/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(108)
err = routes.MoveTopicSubmit(w,req,user,extraData)
case "/topic/like/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(109)
err = routes.LikeTopicSubmit(w,req,user,extraData)
case "/topic/attach/add/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
return err
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(110)
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
case "/topic/attach/remove/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(111)
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
default:
counters.RouteViewCounter.Bump(112)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.ViewTopic(w,req,user, head, extraData)
}
case "/reply":
switch(req.URL.Path) {
case "/reply/create/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
return err
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(113)
err = routes.CreateReplySubmit(w,req,user)
case "/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(114)
err = routes.ReplyEditSubmit(w,req,user,extraData)
case "/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(115)
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
case "/reply/like/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(116)
err = routes.ReplyLikeSubmit(w,req,user,extraData)
case "/reply/attach/add/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
return err
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(117)
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
case "/reply/attach/remove/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(118)
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
}
case "/profile":
switch(req.URL.Path) {
case "/profile/reply/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(119)
err = routes.ProfileReplyCreateSubmit(w,req,user)
case "/profile/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(120)
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
case "/profile/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(121)
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
}
case "/poll":
switch(req.URL.Path) {
case "/poll/vote/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(122)
err = routes.PollVote(w,req,user,extraData)
case "/poll/results/":
counters.RouteViewCounter.Bump(123)
err = routes.PollResults(w,req,user,extraData)
}
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
counters.RouteViewCounter.Bump(124)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountLogin(w,req,user,head)
case "/accounts/create/":
counters.RouteViewCounter.Bump(125)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountRegister(w,req,user,head)
case "/accounts/logout/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = common.MemberOnly(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(126)
err = routes.AccountLogout(w,req,user)
case "/accounts/login/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(127)
err = routes.AccountLoginSubmit(w,req,user)
case "/accounts/mfa_verify/":
counters.RouteViewCounter.Bump(128)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountLoginMFAVerify(w,req,user,head)
case "/accounts/mfa_verify/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(129)
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
case "/accounts/create/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(130)
err = routes.AccountRegisterSubmit(w,req,user)
case "/accounts/password-reset/":
counters.RouteViewCounter.Bump(131)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountPasswordReset(w,req,user,head)
case "/accounts/password-reset/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(132)
err = routes.AccountPasswordResetSubmit(w,req,user)
case "/accounts/password-reset/token/":
counters.RouteViewCounter.Bump(133)
head, err := common.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountPasswordResetToken(w,req,user,head)
case "/accounts/password-reset/token/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
return err
}
counters.RouteViewCounter.Bump(134)
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
}
/*case "/sitemaps": // TODO: Count these views
req.URL.Path += extraData
err = sitemapSwitch(w,req)*/
case "/uploads":
if extraData == "" {
return common.NotFound(w,req,nil)
}
gzw, ok := w.(common.GzipResponseWriter)
if ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Type")
w.Header().Del("Content-Encoding")
}
counters.RouteViewCounter.Bump(136)
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
r.UploadHandler(w,req) // TODO: Count these views
return nil
case "":
// Stop the favicons, robots.txt file, etc. resolving to the topics list
// TODO: Add support for favicons and robots.txt files
switch(extraData) {
case "robots.txt":
counters.RouteViewCounter.Bump(138)
return routes.RobotsTxt(w,req)
case "favicon.ico":
req.URL.Path = "/static"+req.URL.Path+extraData
//log.Print("req.URL.Path: ",req.URL.Path)
routes.StaticFile(w,req)
return nil
/*case "sitemap.xml":
counters.RouteViewCounter.Bump(139)
return routes.SitemapXml(w,req)*/
}
return common.NotFound(w,req,nil)
default:
// A fallback for dynamic routes, e.g. ones declared by plugins
r.RLock()
handle, ok := r.extraRoutes[req.URL.Path]
r.RUnlock()
if ok {
counters.RouteViewCounter.Bump(135) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData
return handle(w,req,user)
}
lowerPath := strings.ToLower(req.URL.Path)
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
r.SuspiciousRequest(req,"Bad Route")
} else {
r.DumpRequest(req,"Bad Route")
}
counters.RouteViewCounter.Bump(140)
return common.NotFound(w,req,nil)
}
return err
}