gosora/gen_router.go

2947 lines
83 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"
"time"
c "github.com/Azareal/Gosora/common"
co "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/uutils"
"github.com/Azareal/Gosora/routes"
"github.com/Azareal/Gosora/routes/panel"
//"github.com/andybalholm/brotli"
)
var ErrNoRoute = errors.New("That route doesn't exist.")
// TODO: What about the /uploads/ route? x.x
var RouteMap = map[string]interface{}{
"routes.Error": routes.Error,
"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": c.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.ForumsOrderSubmit": panel.ForumsOrderSubmit,
"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.UsersAvatarSubmit": panel.UsersAvatarSubmit,
"panel.UsersAvatarRemoveSubmit": panel.UsersAvatarRemoveSubmit,
"panel.AnalyticsViews": panel.AnalyticsViews,
"panel.AnalyticsRoutes": panel.AnalyticsRoutes,
"panel.AnalyticsRoutesPerf": panel.AnalyticsRoutesPerf,
"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.AnalyticsMemory": panel.AnalyticsMemory,
"panel.AnalyticsActiveMemory": panel.AnalyticsActiveMemory,
"panel.AnalyticsTopics": panel.AnalyticsTopics,
"panel.AnalyticsForums": panel.AnalyticsForums,
"panel.AnalyticsPerf": panel.AnalyticsPerf,
"panel.Groups": panel.Groups,
"panel.GroupsEdit": panel.GroupsEdit,
"panel.GroupsEditPromotions": panel.GroupsEditPromotions,
"panel.GroupsPromotionsCreateSubmit": panel.GroupsPromotionsCreateSubmit,
"panel.GroupsPromotionsDeleteSubmit": panel.GroupsPromotionsDeleteSubmit,
"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.LogsAdmin": panel.LogsAdmin,
"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.AccountEditRevokeAvatarSubmit": routes.AccountEditRevokeAvatarSubmit,
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
"routes.AccountEditPrivacy": routes.AccountEditPrivacy,
"routes.AccountEditPrivacySubmit": routes.AccountEditPrivacySubmit,
"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.AccountBlocked": routes.AccountBlocked,
"routes.LevelList": routes.LevelList,
"routes.Convos": routes.Convos,
"routes.ConvosCreate": routes.ConvosCreate,
"routes.Convo": routes.Convo,
"routes.ConvosCreateSubmit": routes.ConvosCreateSubmit,
"routes.ConvosCreateReplySubmit": routes.ConvosCreateReplySubmit,
"routes.ConvosDeleteReplySubmit": routes.ConvosDeleteReplySubmit,
"routes.ConvosEditReplySubmit": routes.ConvosEditReplySubmit,
"routes.RelationsBlockCreate": routes.RelationsBlockCreate,
"routes.RelationsBlockCreateSubmit": routes.RelationsBlockCreateSubmit,
"routes.RelationsBlockRemove": routes.RelationsBlockRemove,
"routes.RelationsBlockRemoveSubmit": routes.RelationsBlockRemoveSubmit,
"routes.ViewProfile": routes.ViewProfile,
"routes.BanUserSubmit": routes.BanUserSubmit,
"routes.UnbanUser": routes.UnbanUser,
"routes.ActivateUser": routes.ActivateUser,
"routes.IPSearch": routes.IPSearch,
"routes.DeletePostsSubmit": routes.DeletePostsSubmit,
"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.UnlikeTopicSubmit": routes.UnlikeTopicSubmit,
"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.ReplyUnlikeSubmit": routes.ReplyUnlikeSubmit,
"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.OpenSearchXml": routes.OpenSearchXml,
"routes.Favicon": routes.Favicon,
"routes.BadRoute": routes.BadRoute,
"routes.HTTPSRedirect": routes.HTTPSRedirect,
}
// ! NEVER RELY ON THESE REMAINING THE SAME BETWEEN COMMITS
var routeMapEnum = map[string]int{
"routes.Error": 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.ForumsOrderSubmit": 20,
"panel.ForumsEdit": 21,
"panel.ForumsEditSubmit": 22,
"panel.ForumsEditPermsSubmit": 23,
"panel.ForumsEditPermsAdvance": 24,
"panel.ForumsEditPermsAdvanceSubmit": 25,
"panel.Settings": 26,
"panel.SettingEdit": 27,
"panel.SettingEditSubmit": 28,
"panel.WordFilters": 29,
"panel.WordFiltersCreateSubmit": 30,
"panel.WordFiltersEdit": 31,
"panel.WordFiltersEditSubmit": 32,
"panel.WordFiltersDeleteSubmit": 33,
"panel.Pages": 34,
"panel.PagesCreateSubmit": 35,
"panel.PagesEdit": 36,
"panel.PagesEditSubmit": 37,
"panel.PagesDeleteSubmit": 38,
"panel.Themes": 39,
"panel.ThemesSetDefault": 40,
"panel.ThemesMenus": 41,
"panel.ThemesMenusEdit": 42,
"panel.ThemesMenuItemEdit": 43,
"panel.ThemesMenuItemEditSubmit": 44,
"panel.ThemesMenuItemCreateSubmit": 45,
"panel.ThemesMenuItemDeleteSubmit": 46,
"panel.ThemesMenuItemOrderSubmit": 47,
"panel.ThemesWidgets": 48,
"panel.ThemesWidgetsEditSubmit": 49,
"panel.ThemesWidgetsCreateSubmit": 50,
"panel.ThemesWidgetsDeleteSubmit": 51,
"panel.Plugins": 52,
"panel.PluginsActivate": 53,
"panel.PluginsDeactivate": 54,
"panel.PluginsInstall": 55,
"panel.Users": 56,
"panel.UsersEdit": 57,
"panel.UsersEditSubmit": 58,
"panel.UsersAvatarSubmit": 59,
"panel.UsersAvatarRemoveSubmit": 60,
"panel.AnalyticsViews": 61,
"panel.AnalyticsRoutes": 62,
"panel.AnalyticsRoutesPerf": 63,
"panel.AnalyticsAgents": 64,
"panel.AnalyticsSystems": 65,
"panel.AnalyticsLanguages": 66,
"panel.AnalyticsReferrers": 67,
"panel.AnalyticsRouteViews": 68,
"panel.AnalyticsAgentViews": 69,
"panel.AnalyticsForumViews": 70,
"panel.AnalyticsSystemViews": 71,
"panel.AnalyticsLanguageViews": 72,
"panel.AnalyticsReferrerViews": 73,
"panel.AnalyticsPosts": 74,
"panel.AnalyticsMemory": 75,
"panel.AnalyticsActiveMemory": 76,
"panel.AnalyticsTopics": 77,
"panel.AnalyticsForums": 78,
"panel.AnalyticsPerf": 79,
"panel.Groups": 80,
"panel.GroupsEdit": 81,
"panel.GroupsEditPromotions": 82,
"panel.GroupsPromotionsCreateSubmit": 83,
"panel.GroupsPromotionsDeleteSubmit": 84,
"panel.GroupsEditPerms": 85,
"panel.GroupsEditSubmit": 86,
"panel.GroupsEditPermsSubmit": 87,
"panel.GroupsCreateSubmit": 88,
"panel.Backups": 89,
"panel.LogsRegs": 90,
"panel.LogsMod": 91,
"panel.LogsAdmin": 92,
"panel.Debug": 93,
"panel.Dashboard": 94,
"routes.AccountEdit": 95,
"routes.AccountEditPassword": 96,
"routes.AccountEditPasswordSubmit": 97,
"routes.AccountEditAvatarSubmit": 98,
"routes.AccountEditRevokeAvatarSubmit": 99,
"routes.AccountEditUsernameSubmit": 100,
"routes.AccountEditPrivacy": 101,
"routes.AccountEditPrivacySubmit": 102,
"routes.AccountEditMFA": 103,
"routes.AccountEditMFASetup": 104,
"routes.AccountEditMFASetupSubmit": 105,
"routes.AccountEditMFADisableSubmit": 106,
"routes.AccountEditEmail": 107,
"routes.AccountEditEmailTokenSubmit": 108,
"routes.AccountLogins": 109,
"routes.AccountBlocked": 110,
"routes.LevelList": 111,
"routes.Convos": 112,
"routes.ConvosCreate": 113,
"routes.Convo": 114,
"routes.ConvosCreateSubmit": 115,
"routes.ConvosCreateReplySubmit": 116,
"routes.ConvosDeleteReplySubmit": 117,
"routes.ConvosEditReplySubmit": 118,
"routes.RelationsBlockCreate": 119,
"routes.RelationsBlockCreateSubmit": 120,
"routes.RelationsBlockRemove": 121,
"routes.RelationsBlockRemoveSubmit": 122,
"routes.ViewProfile": 123,
"routes.BanUserSubmit": 124,
"routes.UnbanUser": 125,
"routes.ActivateUser": 126,
"routes.IPSearch": 127,
"routes.DeletePostsSubmit": 128,
"routes.CreateTopicSubmit": 129,
"routes.EditTopicSubmit": 130,
"routes.DeleteTopicSubmit": 131,
"routes.StickTopicSubmit": 132,
"routes.UnstickTopicSubmit": 133,
"routes.LockTopicSubmit": 134,
"routes.UnlockTopicSubmit": 135,
"routes.MoveTopicSubmit": 136,
"routes.LikeTopicSubmit": 137,
"routes.UnlikeTopicSubmit": 138,
"routes.AddAttachToTopicSubmit": 139,
"routes.RemoveAttachFromTopicSubmit": 140,
"routes.ViewTopic": 141,
"routes.CreateReplySubmit": 142,
"routes.ReplyEditSubmit": 143,
"routes.ReplyDeleteSubmit": 144,
"routes.ReplyLikeSubmit": 145,
"routes.ReplyUnlikeSubmit": 146,
"routes.AddAttachToReplySubmit": 147,
"routes.RemoveAttachFromReplySubmit": 148,
"routes.ProfileReplyCreateSubmit": 149,
"routes.ProfileReplyEditSubmit": 150,
"routes.ProfileReplyDeleteSubmit": 151,
"routes.PollVote": 152,
"routes.PollResults": 153,
"routes.AccountLogin": 154,
"routes.AccountRegister": 155,
"routes.AccountLogout": 156,
"routes.AccountLoginSubmit": 157,
"routes.AccountLoginMFAVerify": 158,
"routes.AccountLoginMFAVerifySubmit": 159,
"routes.AccountRegisterSubmit": 160,
"routes.AccountPasswordReset": 161,
"routes.AccountPasswordResetSubmit": 162,
"routes.AccountPasswordResetToken": 163,
"routes.AccountPasswordResetTokenSubmit": 164,
"routes.DynamicRoute": 165,
"routes.UploadedFile": 166,
"routes.StaticFile": 167,
"routes.RobotsTxt": 168,
"routes.SitemapXml": 169,
"routes.OpenSearchXml": 170,
"routes.Favicon": 171,
"routes.BadRoute": 172,
"routes.HTTPSRedirect": 173,
}
var reverseRouteMapEnum = map[int]string{
0: "routes.Error",
1: "routes.Overview",
2: "routes.CustomPage",
3: "routes.ForumList",
4: "routes.ViewForum",
5: "routes.ChangeTheme",
6: "routes.ShowAttachment",
7: "common.RouteWebsockets",
8: "routeAPIPhrases",
9: "routes.APIMe",
10: "routeJSAntispam",
11: "routeAPI",
12: "routes.ReportSubmit",
13: "routes.TopicListMostViewed",
14: "routes.CreateTopic",
15: "routes.TopicList",
16: "panel.Forums",
17: "panel.ForumsCreateSubmit",
18: "panel.ForumsDelete",
19: "panel.ForumsDeleteSubmit",
20: "panel.ForumsOrderSubmit",
21: "panel.ForumsEdit",
22: "panel.ForumsEditSubmit",
23: "panel.ForumsEditPermsSubmit",
24: "panel.ForumsEditPermsAdvance",
25: "panel.ForumsEditPermsAdvanceSubmit",
26: "panel.Settings",
27: "panel.SettingEdit",
28: "panel.SettingEditSubmit",
29: "panel.WordFilters",
30: "panel.WordFiltersCreateSubmit",
31: "panel.WordFiltersEdit",
32: "panel.WordFiltersEditSubmit",
33: "panel.WordFiltersDeleteSubmit",
34: "panel.Pages",
35: "panel.PagesCreateSubmit",
36: "panel.PagesEdit",
37: "panel.PagesEditSubmit",
38: "panel.PagesDeleteSubmit",
39: "panel.Themes",
40: "panel.ThemesSetDefault",
41: "panel.ThemesMenus",
42: "panel.ThemesMenusEdit",
43: "panel.ThemesMenuItemEdit",
44: "panel.ThemesMenuItemEditSubmit",
45: "panel.ThemesMenuItemCreateSubmit",
46: "panel.ThemesMenuItemDeleteSubmit",
47: "panel.ThemesMenuItemOrderSubmit",
48: "panel.ThemesWidgets",
49: "panel.ThemesWidgetsEditSubmit",
50: "panel.ThemesWidgetsCreateSubmit",
51: "panel.ThemesWidgetsDeleteSubmit",
52: "panel.Plugins",
53: "panel.PluginsActivate",
54: "panel.PluginsDeactivate",
55: "panel.PluginsInstall",
56: "panel.Users",
57: "panel.UsersEdit",
58: "panel.UsersEditSubmit",
59: "panel.UsersAvatarSubmit",
60: "panel.UsersAvatarRemoveSubmit",
61: "panel.AnalyticsViews",
62: "panel.AnalyticsRoutes",
63: "panel.AnalyticsRoutesPerf",
64: "panel.AnalyticsAgents",
65: "panel.AnalyticsSystems",
66: "panel.AnalyticsLanguages",
67: "panel.AnalyticsReferrers",
68: "panel.AnalyticsRouteViews",
69: "panel.AnalyticsAgentViews",
70: "panel.AnalyticsForumViews",
71: "panel.AnalyticsSystemViews",
72: "panel.AnalyticsLanguageViews",
73: "panel.AnalyticsReferrerViews",
74: "panel.AnalyticsPosts",
75: "panel.AnalyticsMemory",
76: "panel.AnalyticsActiveMemory",
77: "panel.AnalyticsTopics",
78: "panel.AnalyticsForums",
79: "panel.AnalyticsPerf",
80: "panel.Groups",
81: "panel.GroupsEdit",
82: "panel.GroupsEditPromotions",
83: "panel.GroupsPromotionsCreateSubmit",
84: "panel.GroupsPromotionsDeleteSubmit",
85: "panel.GroupsEditPerms",
86: "panel.GroupsEditSubmit",
87: "panel.GroupsEditPermsSubmit",
88: "panel.GroupsCreateSubmit",
89: "panel.Backups",
90: "panel.LogsRegs",
91: "panel.LogsMod",
92: "panel.LogsAdmin",
93: "panel.Debug",
94: "panel.Dashboard",
95: "routes.AccountEdit",
96: "routes.AccountEditPassword",
97: "routes.AccountEditPasswordSubmit",
98: "routes.AccountEditAvatarSubmit",
99: "routes.AccountEditRevokeAvatarSubmit",
100: "routes.AccountEditUsernameSubmit",
101: "routes.AccountEditPrivacy",
102: "routes.AccountEditPrivacySubmit",
103: "routes.AccountEditMFA",
104: "routes.AccountEditMFASetup",
105: "routes.AccountEditMFASetupSubmit",
106: "routes.AccountEditMFADisableSubmit",
107: "routes.AccountEditEmail",
108: "routes.AccountEditEmailTokenSubmit",
109: "routes.AccountLogins",
110: "routes.AccountBlocked",
111: "routes.LevelList",
112: "routes.Convos",
113: "routes.ConvosCreate",
114: "routes.Convo",
115: "routes.ConvosCreateSubmit",
116: "routes.ConvosCreateReplySubmit",
117: "routes.ConvosDeleteReplySubmit",
118: "routes.ConvosEditReplySubmit",
119: "routes.RelationsBlockCreate",
120: "routes.RelationsBlockCreateSubmit",
121: "routes.RelationsBlockRemove",
122: "routes.RelationsBlockRemoveSubmit",
123: "routes.ViewProfile",
124: "routes.BanUserSubmit",
125: "routes.UnbanUser",
126: "routes.ActivateUser",
127: "routes.IPSearch",
128: "routes.DeletePostsSubmit",
129: "routes.CreateTopicSubmit",
130: "routes.EditTopicSubmit",
131: "routes.DeleteTopicSubmit",
132: "routes.StickTopicSubmit",
133: "routes.UnstickTopicSubmit",
134: "routes.LockTopicSubmit",
135: "routes.UnlockTopicSubmit",
136: "routes.MoveTopicSubmit",
137: "routes.LikeTopicSubmit",
138: "routes.UnlikeTopicSubmit",
139: "routes.AddAttachToTopicSubmit",
140: "routes.RemoveAttachFromTopicSubmit",
141: "routes.ViewTopic",
142: "routes.CreateReplySubmit",
143: "routes.ReplyEditSubmit",
144: "routes.ReplyDeleteSubmit",
145: "routes.ReplyLikeSubmit",
146: "routes.ReplyUnlikeSubmit",
147: "routes.AddAttachToReplySubmit",
148: "routes.RemoveAttachFromReplySubmit",
149: "routes.ProfileReplyCreateSubmit",
150: "routes.ProfileReplyEditSubmit",
151: "routes.ProfileReplyDeleteSubmit",
152: "routes.PollVote",
153: "routes.PollResults",
154: "routes.AccountLogin",
155: "routes.AccountRegister",
156: "routes.AccountLogout",
157: "routes.AccountLoginSubmit",
158: "routes.AccountLoginMFAVerify",
159: "routes.AccountLoginMFAVerifySubmit",
160: "routes.AccountRegisterSubmit",
161: "routes.AccountPasswordReset",
162: "routes.AccountPasswordResetSubmit",
163: "routes.AccountPasswordResetToken",
164: "routes.AccountPasswordResetTokenSubmit",
165: "routes.DynamicRoute",
166: "routes.UploadedFile",
167: "routes.StaticFile",
168: "routes.RobotsTxt",
169: "routes.SitemapXml",
170: "routes.OpenSearchXml",
171: "routes.Favicon",
172: "routes.BadRoute",
173: "routes.HTTPSRedirect",
}
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,
"slurp": 15,
"exabot": 16,
"mojeek": 17,
"cliqz": 18,
"datenbank": 19,
"baidu": 20,
"sogou": 21,
"toutiao": 22,
"haosou": 23,
"duckduckgo": 24,
"seznambot": 25,
"discord": 26,
"twitter": 27,
"facebook": 28,
"cloudflare": 29,
"archive_org": 30,
"uptimebot": 31,
"slackbot": 32,
"apple": 33,
"discourse": 34,
"mattermost": 35,
"alexa": 36,
"lynx": 37,
"blank": 38,
"malformed": 39,
"suspicious": 40,
"semrush": 41,
"dotbot": 42,
"ahrefs": 43,
"proximic": 44,
"megaindex": 45,
"majestic": 46,
"cocolyze": 47,
"babbar": 48,
"surdotly": 49,
"netcraft": 50,
"blexbot": 51,
"burf": 52,
"aspiegel": 53,
"mail_ru": 54,
"ccbot": 55,
"zgrab": 56,
"cloudsystemnetworks": 57,
"curl": 58,
"python": 59,
"go": 60,
"headlesschrome": 61,
"awesome_bot": 62,
}
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: "slurp",
16: "exabot",
17: "mojeek",
18: "cliqz",
19: "datenbank",
20: "baidu",
21: "sogou",
22: "toutiao",
23: "haosou",
24: "duckduckgo",
25: "seznambot",
26: "discord",
27: "twitter",
28: "facebook",
29: "cloudflare",
30: "archive_org",
31: "uptimebot",
32: "slackbot",
33: "apple",
34: "discourse",
35: "mattermost",
36: "alexa",
37: "lynx",
38: "blank",
39: "malformed",
40: "suspicious",
41: "semrush",
42: "dotbot",
43: "ahrefs",
44: "proximic",
45: "megaindex",
46: "majestic",
47: "cocolyze",
48: "babbar",
49: "surdotly",
50: "netcraft",
51: "blexbot",
52: "burf",
53: "aspiegel",
54: "mail_ru",
55: "ccbot",
56: "zgrab",
57: "cloudsystemnetworks",
58: "curl",
59: "python",
60: "go",
61: "headlesschrome",
62: "awesome_bot",
}
var markToAgent = map[string]string{
"OPR": "opera",
"Chrome": "chrome",
"Firefox": "firefox",
"Safari": "safari",
"MSIE": "internetexplorer",
"Trident": "trident",
"Edge": "edge",
"Lynx": "lynx",
"SamsungBrowser": "samsung",
"UCBrowser": "ucbrowser",
"Google": "googlebot",
"Googlebot": "googlebot",
"yandex": "yandex",
"DuckDuckBot": "duckduckgo",
"DuckDuckGo": "duckduckgo",
"Baiduspider": "baidu",
"Sogou": "sogou",
"ToutiaoSpider": "toutiao",
"360Spider": "haosou",
"bingbot": "bing",
"BingPreview": "bing",
"msnbot": "bing",
"Slurp": "slurp",
"Exabot": "exabot",
"MojeekBot": "mojeek",
"Cliqzbot": "cliqz",
"netEstate": "datenbank",
"SeznamBot": "seznambot",
"CloudFlare": "cloudflare",
"archive": "archive_org",
"Uptimebot": "uptimebot",
"Slackbot": "slackbot",
"Slack": "slackbot",
"Discordbot": "discord",
"Twitterbot": "twitter",
"facebookexternalhit": "facebook",
"Facebot": "facebook",
"Applebot": "apple",
"Discourse": "discourse",
"mattermost": "mattermost",
"ia_archiver": "alexa",
"SemrushBot": "semrush",
"DotBot": "dotbot",
"AhrefsBot": "ahrefs",
"proximic": "proximic",
"MegaIndex": "megaindex",
"MJ12bot": "majestic",
"mj12bot": "majestic",
"Cocolyzebot": "cocolyze",
"Barkrowler": "babbar",
"SurdotlyBot": "surdotly",
"NetcraftSurveyAgent": "netcraft",
"BLEXBot": "blexbot",
"Burf": "burf",
"AspiegelBot": "aspiegel",
"RU_Bot": "mail_ru",
"CCBot": "ccbot",
"zgrab": "zgrab",
"Nimbostratus": "cloudsystemnetworks",
"curl": "curl",
"python": "python",
"Go": "go",
"HeadlessChrome": "headlesschrome",
"awesome_bot": "awesome_bot",
}
var markToID = map[string]int{
"OPR": 3,
"Chrome": 2,
"Firefox": 1,
"Safari": 4,
"MSIE": 6,
"Trident": 7,
"Edge": 5,
"Lynx": 37,
"SamsungBrowser": 10,
"UCBrowser": 11,
"Google": 12,
"Googlebot": 12,
"yandex": 13,
"DuckDuckBot": 24,
"DuckDuckGo": 24,
"Baiduspider": 20,
"Sogou": 21,
"ToutiaoSpider": 22,
"360Spider": 23,
"bingbot": 14,
"BingPreview": 14,
"msnbot": 14,
"Slurp": 15,
"Exabot": 16,
"MojeekBot": 17,
"Cliqzbot": 18,
"netEstate": 19,
"SeznamBot": 25,
"CloudFlare": 29,
"archive": 30,
"Uptimebot": 31,
"Slackbot": 32,
"Slack": 32,
"Discordbot": 26,
"Twitterbot": 27,
"facebookexternalhit": 28,
"Facebot": 28,
"Applebot": 33,
"Discourse": 34,
"mattermost": 35,
"ia_archiver": 36,
"SemrushBot": 41,
"DotBot": 42,
"AhrefsBot": 43,
"proximic": 44,
"MegaIndex": 45,
"MJ12bot": 46,
"mj12bot": 46,
"Cocolyzebot": 47,
"Barkrowler": 48,
"SurdotlyBot": 49,
"NetcraftSurveyAgent": 50,
"BLEXBot": 51,
"Burf": 52,
"AspiegelBot": 53,
"RU_Bot": 54,
"CCBot": 55,
"zgrab": 56,
"Nimbostratus": 57,
"curl": 58,
"python": 59,
"Go": 60,
"HeadlessChrome": 61,
"awesome_bot": 62,
}
/*var agentRank = map[string]int{
"opera":9,
"chrome":8,
"safari":1,
}*/
// TODO: Stop spilling these into the package scope?
func init() {
_ = time.Now()
co.SetRouteMapEnum(routeMapEnum)
co.SetReverseRouteMapEnum(reverseRouteMapEnum)
co.SetAgentMapEnum(agentMapEnum)
co.SetReverseAgentMapEnum(reverseAgentMapEnum)
co.SetOSMapEnum(osMapEnum)
co.SetReverseOSMapEnum(reverseOSMapEnum)
c.Chrome = agentMapEnum["chrome"]
c.Firefox = agentMapEnum["firefox"]
ame := agentMapEnum
c.SimpleBots = []int{
ame["semrush"],
ame["ahrefs"],
ame["python"],
ame["go"],
ame["curl"],
}
}
type WriterIntercept struct {
http.ResponseWriter
}
func NewWriterIntercept(w http.ResponseWriter) *WriterIntercept {
return &WriterIntercept{w}
}
var wiMaxAge = "max-age=" + strconv.Itoa(int(c.Day))
func (wi *WriterIntercept) WriteHeader(code int) {
if code == 200 {
h := wi.ResponseWriter.Header()
h.Set("Cache-Control", wiMaxAge)
h.Set("Vary", "Accept-Encoding")
}
wi.ResponseWriter.WriteHeader(code)
}
// HTTPSRedirect is a connection handler which redirects all HTTP requests to HTTPS
type HTTPSRedirect struct {}
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Connection", "close")
co.RouteViewCounter.Bump(173)
dest := "https://" + req.Host + req.URL.String()
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
}
type GenRouter struct {
UploadHandler func(http.ResponseWriter, *http.Request)
extraRoutes map[string]func(http.ResponseWriter, *http.Request, *c.User) c.RouteError
requestLogger *log.Logger
sync.RWMutex
}
func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
f, err := os.OpenFile("./logs/reqs-"+strconv.FormatInt(c.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, *c.User) c.RouteError),
requestLogger: log.New(f, "", log.LstdFlags),
}, nil
}
func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *http.Request, u *c.User) {
if err.Handled() {
return
}
if err.Type() == "system" {
c.InternalErrorJSQ(err, w, req, err.JSON())
return
}
c.LocalErrorJSQ(err.Error(), w, req, u, err.JSON())
}
func (r *GenRouter) Handle(_ string, _ http.Handler) {
}
func (r *GenRouter) HandleFunc(pattern string, h func(http.ResponseWriter, *http.Request, *c.User) c.RouteError) {
r.Lock()
defer r.Unlock()
r.extraRoutes[pattern] = h
}
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
}
// TODO: Use strings builder?
func (r *GenRouter) DumpRequest(req *http.Request, pre string) {
var heads string
for key, value := range req.Header {
for _, vvalue := range value {
heads += "Head " + c.SanitiseSingleLine(key) + ": " + c.SanitiseSingleLine(vvalue) + "\n"
}
}
r.requestLogger.Print(pre +
"\nUA: " + c.SanitiseSingleLine(req.UserAgent()) + "\n" +
"Method: " + c.SanitiseSingleLine(req.Method) + "\n" + heads +
"Host: " + c.SanitiseSingleLine(req.Host) + "\n" +
"URL.Path: " + c.SanitiseSingleLine(req.URL.Path) + "\n" +
"URL.RawQuery: " + c.SanitiseSingleLine(req.URL.RawQuery) + "\n" +
"Ref: " + c.SanitiseSingleLine(req.Referer()) + "\n" +
"IP: " + req.RemoteAddr + "\n")
}
func (r *GenRouter) SuspiciousRequest(req *http.Request, pre string) {
if pre != "" {
pre += "\n"
}
r.DumpRequest(req,pre+"Suspicious Request")
co.AgentViewCounter.Bump(40)
}
func isLocalHost(h string) bool {
return h=="localhost" || h=="127.0.0.1" || h=="::1"
}
//var brPool = sync.Pool{}
var gzipPool = sync.Pool{}
//var uaBufPool = sync.Pool{}
// 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) {
malformedRequest := func(typ int) {
w.WriteHeader(200) // 400
w.Write([]byte(""))
r.DumpRequest(req,"Malformed Request T"+strconv.Itoa(typ))
co.AgentViewCounter.Bump(39)
}
// Split the Host and Port string
var shost, sport string
if req.Host[0]=='[' {
spl := strings.Split(req.Host,"]")
if len(spl) > 2 {
malformedRequest(0)
return
}
shost = strings.TrimPrefix(spl[0],"[")
sport = strings.TrimPrefix(spl[1],":")
} else if strings.Contains(req.Host,":") {
spl := strings.Split(req.Host,":")
if len(spl) > 2 {
malformedRequest(1)
return
}
shost = spl[0]
//if len(spl)==2 {
sport = spl[1]
//}
} else {
shost = req.Host
}
// TODO: Reject requests from non-local IPs, if the site host is set to localhost or a localhost IP
if !c.Config.LoosePort && c.Site.PortInt != 80 && c.Site.PortInt != 443 && sport != c.Site.Port {
malformedRequest(2)
return
}
// Redirect www. and local IP requests to the right place
if strings.HasPrefix(shost, "www.") || c.Site.LocalHost {
if shost == "www." + c.Site.Host || (c.Site.LocalHost && shost != c.Site.Host && isLocalHost(shost)) {
// TODO: Abstract the redirect logic?
w.Header().Set("Connection", "close")
var s string
if c.Config.SslSchema {
s = "s"
}
var p string
if c.Site.PortInt != 80 && c.Site.PortInt != 443 {
p = ":"+c.Site.Port
}
dest := "http"+s+"://" + c.Site.Host+p + 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] != '/' || (!c.Config.LooseHost && shost != c.Site.Host) {
malformedRequest(3)
return
}
if c.Dev.FullReqLog {
r.DumpRequest(req,"")
}
// TODO: Cover more suspicious strings and at a lower layer than this
for _, ch := range req.URL.Path { //char
if ch != '&' && !(ch > 44 && ch < 58) && ch != '=' && ch != '?' && !(ch > 64 && ch < 91) && ch != '\\' && ch != '_' && !(ch > 96 && ch < 123) {
r.SuspiciousRequest(req,"Bad char '"+string(ch)+"' in path")
break
}
}
lp := strings.ToLower(req.URL.Path)
// TODO: Flag any requests which has a dot with anything but a number after that
// TODO: Use HasSuffix to avoid over-scanning?
if strings.Contains(lp,"..")/* || strings.Contains(lp,"--")*/ || strings.Contains(lp,".php") || strings.Contains(lp,".asp") || strings.Contains(lp,".cgi") || strings.Contains(lp,".py") || strings.Contains(lp,".sql") || strings.Contains(lp,".act") { //.action
r.SuspiciousRequest(req,"Bad snippet in path")
}
// Indirect the default route onto a different one
if req.URL.Path == "/" {
req.URL.Path = c.Config.DefaultPath
}
//log.Print("URL.Path: ", req.URL.Path)
prefix := req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1]
// TODO: Use the same hook table as downstream
hTbl := c.GetHookTable()
skip, ferr := c.H_router_after_filters_hook(hTbl, w, req, prefix)
if skip || ferr != nil {
return
}
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
h.Set("X-Content-Type-Options", "nosniff")
if c.Config.RefNoRef || !c.Config.SslSchema {
h.Set("Referrer-Policy","no-referrer")
} else {
h.Set("Referrer-Policy","strict-origin")
}
}
if c.Dev.SuperDebug {
r.DumpRequest(req,"before routes.StaticFile")
}
// Increment the request counter
if !c.Config.DisableAnalytics {
co.GlobalViewCounter.Bump()
}
if prefix == "/s" { //old prefix: /static
if !c.Config.DisableAnalytics {
co.RouteViewCounter.Bump(167)
}
routes.StaticFile(w, req)
return
}
// TODO: Handle JS routes
if atomic.LoadInt32(&c.IsDBDown) == 1 {
c.DatabaseError(w, req)
return
}
if c.Dev.SuperDebug {
r.requestLogger.Print("before PreRoute")
}
/*if c.Dev.QuicPort != 0 {
w.Header().Set("Alt-Svc", "quic=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h3-24=\":"+strconv.Itoa(c.Dev.QuicPort)+"\"; ma=3600, h2=\":443\"; ma=3600")
}*/
// 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
var agent int
if !c.Config.DisableAnalytics {
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 == "" {
co.AgentViewCounter.Bump(38)
if c.Dev.DebugMode {
var pre string
for _, char := range req.UserAgent() {
pre += strconv.Itoa(int(char)) + " "
}
r.DumpRequest(req,"Blank UA: " + pre)
}
} else {
// WIP UA Parser
//var ii = uaBufPool.Get()
var buf []byte
//if ii != nil {
// buf = ii.([]byte)
//}
var items []string
var os int
for _, it := range uutils.StringToBytes(ua) {
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
// TODO: Store an index and slice that instead?
buf = append(buf, it)
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' /*|| (it == ':' && bytes.Equal(buf,[]byte("http")))*/ || it == ',' || it == '/' {
if len(buf) != 0 {
if len(buf) > 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(uutils.BytesToString(buf)) {
case "Windows":
os = 1
case "Linux":
os = 2
case "Mac":
os = 3
case "iPhone":
os = 5
case "Android":
os = 4
case "like","compatible","NT","X","KHTML":
// Skip these words
default:
items = append(items, string(buf))
}
}
buf = buf[:0]
}
} else {
// TODO: Test this
items = items[:0]
r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA")
r.requestLogger.Print("UA Buf: ", buf)
r.requestLogger.Print("UA Buf String: ", string(buf))
break
}
}
//uaBufPool.Put(buf)
// Iterate over this in reverse as the real UA tends to be on the right side
for i := len(items) - 1; i >= 0; i-- {
//fAgent, ok := markToAgent[items[i]]
fAgent, ok := markToID[items[i]]
if ok {
agent = fAgent
if agent != 4 {
break
}
}
}
if c.Dev.SuperDebug {
r.requestLogger.Print("parsed agent: ", agent)
r.requestLogger.Print("os: ", os)
r.requestLogger.Printf("items: %+v\n",items)
/*for _, it := range items {
r.requestLogger.Printf("it: %+v\n",string(it))
}*/
}
// Special handling
switch(agent) {
case 2:
if os == 4 {
agent = 8
}
case 4:
if os == 5 {
agent = 9
}
case 7:
// Hack to support IE11, change this after we start logging versions
if strings.Contains(ua,"rv:11") {
agent = 6
}
case 56:
r.SuspiciousRequest(req,"Vuln Scanner")
}
if agent == 0 {
//co.AgentViewCounter.Bump(0)
if c.Dev.DebugMode {
var pre string
for _, char := range req.UserAgent() {
pre += strconv.Itoa(int(char)) + " "
}
r.DumpRequest(req,"Blank UA: " + pre)
} else {
r.requestLogger.Print("unknown ua: ", c.SanitiseSingleLine(ua))
}
}// else {
//co.AgentViewCounter.Bump(agentMapEnum[agent])
co.AgentViewCounter.Bump(agent)
//}
co.OSViewCounter.Bump(os)
}
// TODO: Do we want to track missing language headers too? Maybe as it's own type, e.g. "noheader"?
// TODO: Default to anything other than en, if anything else is present, to avoid over-representing it for multi-linguals?
lang := req.Header.Get("Accept-Language")
if lang != "" {
// TODO: Reduce allocs here
lLang := strings.Split(strings.TrimSpace(lang),"-")
tLang := strings.Split(strings.Split(lLang[0],";")[0],",")
c.DebugDetail("tLang:", tLang)
var llLang string
for _, seg := range tLang {
if seg == "*" {
continue
}
llLang = seg
break
}
c.DebugDetail("llLang:", llLang)
if !co.LangViewCounter.Bump(llLang) {
r.DumpRequest(req,"Invalid ISO Code")
}
} else {
co.LangViewCounter.Bump2(0)
}
if !c.Config.RefNoTrack {
ae := req.Header.Get("Accept-Encoding")
likelyBot := ae == "gzip" || ae == ""
if !likelyBot {
ref := req.Header.Get("Referer") // Check the 'referrer' header too? :P
if ref != "" {
// ? Optimise this a little?
ref = strings.TrimPrefix(strings.TrimPrefix(ref,"http://"),"https://")
ref = strings.Split(ref,"/")[0]
portless := strings.Split(ref,":")[0]
// TODO: Handle c.Site.Host in uppercase too?
if portless != "localhost" && portless != "127.0.0.1" && portless != c.Site.Host {
r.DumpRequest(req,"Ref Route")
co.ReferrerTracker.Bump(ref)
}
}
}
}
}
// Deal with the session stuff, etc.
ucpy, ok := c.PreRoute(w, req)
if !ok {
return
}
user := &ucpy
user.LastAgent = agent
if c.Dev.SuperDebug {
r.requestLogger.Print(
"after PreRoute\n" +
"routeMapEnum: ", routeMapEnum)
}
//log.Println("req: ", req)
// Disable Gzip when SSL is disabled for security reasons?
if prefix != "/ws" {
ae := req.Header.Get("Accept-Encoding")
/*if strings.Contains(ae, "br") {
h := w.Header()
h.Set("Content-Encoding", "br")
var ii = brPool.Get()
var igzw *brotli.Writer
if ii == nil {
igzw = brotli.NewWriter(w)
} else {
igzw = ii.(*brotli.Writer)
igzw.Reset(w)
}
gzw := c.BrResponseWriter{Writer: igzw, ResponseWriter: w}
defer func() {
//h := w.Header()
if h.Get("Content-Encoding") == "br" && h.Get("X-I") == "" {
//log.Print("push br close")
igzw := gzw.Writer.(*brotli.Writer)
igzw.Close()
brPool.Put(igzw)
}
}()
w = gzw
} else */if strings.Contains(ae, "gzip") {
h := w.Header()
h.Set("Content-Encoding", "gzip")
var ii = gzipPool.Get()
var igzw *gzip.Writer
if ii == nil {
igzw = gzip.NewWriter(w)
} else {
igzw = ii.(*gzip.Writer)
igzw.Reset(w)
}
gzw := c.GzipResponseWriter{Writer: igzw, ResponseWriter: w}
defer func() {
//h := w.Header()
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
//log.Print("push gzip close")
igzw := gzw.Writer.(*gzip.Writer)
igzw.Close()
gzipPool.Put(igzw)
}
}()
w = gzw
}
}
skip, ferr = c.H_router_pre_route_hook(hTbl, w, req, user, prefix)
if skip || ferr != nil {
r.handleError(ferr,w,req,user)
return
}
var extraData string
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
}
ferr = r.routeSwitch(w, req, user, prefix, extraData)
if ferr != nil {
r.handleError(ferr,w,req,user)
return
}
/*if !c.Config.DisableAnalytics {
co.RouteViewCounter.Bump(id)
}*/
hTbl.VhookNoRet("router_end", w, req, user, prefix, extraData)
//c.StoppedServer("Profile end")
}
func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *c.User, prefix, extraData string) /*(id int, orerr */c.RouteError/*)*/ {
var err c.RouteError
cn := uutils.Nanotime()
switch(prefix) {
case "/overview":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.Overview(w,req,user,h)
co.RouteViewCounter.Bump3(1, cn)
case "/pages":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.CustomPage(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(2, cn)
case "/forums":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.ForumList(w,req,user,h)
co.RouteViewCounter.Bump3(3, cn)
case "/forum":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.ViewForum(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(4, cn)
case "/theme":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.ChangeTheme(w,req,user)
co.RouteViewCounter.Bump3(5, cn)
case "/attachs":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Encoding")
}
err = routes.ShowAttachment(w,req,user,extraData)
co.RouteViewCounter.Bump3(6, cn)
case "/ws":
req.URL.Path += extraData
err = c.RouteWebsockets(w,req,user)
case "/api":
switch(req.URL.Path) {
case "/api/phrases/":
err = routeAPIPhrases(w,req,user)
co.RouteViewCounter.Bump3(8, cn)
case "/api/me/":
err = routes.APIMe(w,req,user)
co.RouteViewCounter.Bump3(9, cn)
case "/api/watches/":
err = routeJSAntispam(w,req,user)
co.RouteViewCounter.Bump3(10, cn)
default:
err = routeAPI(w,req,user)
co.RouteViewCounter.Bump3(11, cn)
}
case "/report":
err = c.NoBanned(w,req,user)
if err != nil {
return err
}
switch(req.URL.Path) {
case "/report/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReportSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(12, cn)
}
case "/topics":
switch(req.URL.Path) {
case "/topics/most-viewed/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.TopicListMostViewed(w,req,user,h)
co.RouteViewCounter.Bump3(13, cn)
case "/topics/create/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.CreateTopic(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(14, cn)
default:
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.TopicList(w,req,user, h)
co.RouteViewCounter.Bump3(15, cn)
}
case "/panel":
err = c.SuperModOnly(w,req,user)
if err != nil {
return err
}
switch(req.URL.Path) {
case "/panel/forums/":
err = panel.Forums(w,req,user)
co.RouteViewCounter.Bump3(16, cn)
case "/panel/forums/create/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(17, cn)
case "/panel/forums/delete/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsDelete(w,req,user,extraData)
co.RouteViewCounter.Bump3(18, cn)
case "/panel/forums/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(19, cn)
case "/panel/forums/order/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsOrderSubmit(w,req,user)
co.RouteViewCounter.Bump3(20, cn)
case "/panel/forums/edit/":
err = panel.ForumsEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(21, cn)
case "/panel/forums/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(22, cn)
case "/panel/forums/edit/perms/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsEditPermsSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(23, cn)
case "/panel/forums/edit/perms/":
err = panel.ForumsEditPermsAdvance(w,req,user,extraData)
co.RouteViewCounter.Bump3(24, cn)
case "/panel/forums/edit/perms/adv/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ForumsEditPermsAdvanceSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(25, cn)
case "/panel/settings/":
err = panel.Settings(w,req,user)
co.RouteViewCounter.Bump3(26, cn)
case "/panel/settings/edit/":
err = panel.SettingEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(27, cn)
case "/panel/settings/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.SettingEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(28, cn)
case "/panel/settings/word-filters/":
err = panel.WordFilters(w,req,user)
co.RouteViewCounter.Bump3(29, cn)
case "/panel/settings/word-filters/create/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.WordFiltersCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(30, cn)
case "/panel/settings/word-filters/edit/":
err = panel.WordFiltersEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(31, cn)
case "/panel/settings/word-filters/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.WordFiltersEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(32, cn)
case "/panel/settings/word-filters/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.WordFiltersDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(33, cn)
case "/panel/pages/":
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.Pages(w,req,user)
co.RouteViewCounter.Bump3(34, cn)
case "/panel/pages/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.PagesCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(35, cn)
case "/panel/pages/edit/":
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.PagesEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(36, cn)
case "/panel/pages/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.PagesEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(37, cn)
case "/panel/pages/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.PagesDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(38, cn)
case "/panel/themes/":
err = panel.Themes(w,req,user)
co.RouteViewCounter.Bump3(39, cn)
case "/panel/themes/default/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesSetDefault(w,req,user,extraData)
co.RouteViewCounter.Bump3(40, cn)
case "/panel/themes/menus/":
err = panel.ThemesMenus(w,req,user)
co.RouteViewCounter.Bump3(41, cn)
case "/panel/themes/menus/edit/":
err = panel.ThemesMenusEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(42, cn)
case "/panel/themes/menus/item/edit/":
err = panel.ThemesMenuItemEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(43, cn)
case "/panel/themes/menus/item/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesMenuItemEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(44, cn)
case "/panel/themes/menus/item/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesMenuItemCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(45, cn)
case "/panel/themes/menus/item/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesMenuItemDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(46, cn)
case "/panel/themes/menus/item/order/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesMenuItemOrderSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(47, cn)
case "/panel/themes/widgets/":
err = panel.ThemesWidgets(w,req,user)
co.RouteViewCounter.Bump3(48, cn)
case "/panel/themes/widgets/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesWidgetsEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(49, cn)
case "/panel/themes/widgets/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesWidgetsCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(50, cn)
case "/panel/themes/widgets/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.ThemesWidgetsDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(51, cn)
case "/panel/plugins/":
err = panel.Plugins(w,req,user)
co.RouteViewCounter.Bump3(52, cn)
case "/panel/plugins/activate/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.PluginsActivate(w,req,user,extraData)
co.RouteViewCounter.Bump3(53, cn)
case "/panel/plugins/deactivate/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.PluginsDeactivate(w,req,user,extraData)
co.RouteViewCounter.Bump3(54, cn)
case "/panel/plugins/install/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.PluginsInstall(w,req,user,extraData)
co.RouteViewCounter.Bump3(55, cn)
case "/panel/users/":
err = panel.Users(w,req,user)
co.RouteViewCounter.Bump3(56, cn)
case "/panel/users/edit/":
err = panel.UsersEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(57, cn)
case "/panel/users/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.UsersEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(58, cn)
case "/panel/users/avatar/submit/":
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.UsersAvatarSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(59, cn)
case "/panel/users/avatar/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.UsersAvatarRemoveSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(60, cn)
case "/panel/analytics/views/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsViews(w,req,user)
co.RouteViewCounter.Bump3(61, cn)
case "/panel/analytics/routes/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsRoutes(w,req,user)
co.RouteViewCounter.Bump3(62, cn)
case "/panel/analytics/routes-perf/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsRoutesPerf(w,req,user)
co.RouteViewCounter.Bump3(63, cn)
case "/panel/analytics/agents/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsAgents(w,req,user)
co.RouteViewCounter.Bump3(64, cn)
case "/panel/analytics/systems/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsSystems(w,req,user)
co.RouteViewCounter.Bump3(65, cn)
case "/panel/analytics/langs/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsLanguages(w,req,user)
co.RouteViewCounter.Bump3(66, cn)
case "/panel/analytics/referrers/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsReferrers(w,req,user)
co.RouteViewCounter.Bump3(67, cn)
case "/panel/analytics/route/":
err = panel.AnalyticsRouteViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(68, cn)
case "/panel/analytics/agent/":
err = panel.AnalyticsAgentViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(69, cn)
case "/panel/analytics/forum/":
err = panel.AnalyticsForumViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(70, cn)
case "/panel/analytics/system/":
err = panel.AnalyticsSystemViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(71, cn)
case "/panel/analytics/lang/":
err = panel.AnalyticsLanguageViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(72, cn)
case "/panel/analytics/referrer/":
err = panel.AnalyticsReferrerViews(w,req,user,extraData)
co.RouteViewCounter.Bump3(73, cn)
case "/panel/analytics/posts/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsPosts(w,req,user)
co.RouteViewCounter.Bump3(74, cn)
case "/panel/analytics/memory/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsMemory(w,req,user)
co.RouteViewCounter.Bump3(75, cn)
case "/panel/analytics/active-memory/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsActiveMemory(w,req,user)
co.RouteViewCounter.Bump3(76, cn)
case "/panel/analytics/topics/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsTopics(w,req,user)
co.RouteViewCounter.Bump3(77, cn)
case "/panel/analytics/forums/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsForums(w,req,user)
co.RouteViewCounter.Bump3(78, cn)
case "/panel/analytics/perf/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = panel.AnalyticsPerf(w,req,user)
co.RouteViewCounter.Bump3(79, cn)
case "/panel/groups/":
err = panel.Groups(w,req,user)
co.RouteViewCounter.Bump3(80, cn)
case "/panel/groups/edit/":
err = panel.GroupsEdit(w,req,user,extraData)
co.RouteViewCounter.Bump3(81, cn)
case "/panel/groups/edit/promotions/":
err = panel.GroupsEditPromotions(w,req,user,extraData)
co.RouteViewCounter.Bump3(82, cn)
case "/panel/groups/promotions/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.GroupsPromotionsCreateSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(83, cn)
case "/panel/groups/promotions/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.GroupsPromotionsDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(84, cn)
case "/panel/groups/edit/perms/":
err = panel.GroupsEditPerms(w,req,user,extraData)
co.RouteViewCounter.Bump3(85, cn)
case "/panel/groups/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.GroupsEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(86, cn)
case "/panel/groups/edit/perms/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(87, cn)
case "/panel/groups/create/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = panel.GroupsCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(88, cn)
case "/panel/backups/":
err = c.SuperAdminOnly(w,req,user)
if err != nil {
return err
}
if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Encoding")
}
err = panel.Backups(w,req,user,extraData)
co.RouteViewCounter.Bump3(89, cn)
case "/panel/logs/regs/":
err = panel.LogsRegs(w,req,user)
co.RouteViewCounter.Bump3(90, cn)
case "/panel/logs/mod/":
err = panel.LogsMod(w,req,user)
co.RouteViewCounter.Bump3(91, cn)
case "/panel/logs/admin/":
err = panel.LogsAdmin(w,req,user)
co.RouteViewCounter.Bump3(92, cn)
case "/panel/debug/":
err = c.AdminOnly(w,req,user)
if err != nil {
return err
}
err = panel.Debug(w,req,user)
co.RouteViewCounter.Bump3(93, cn)
default:
err = panel.Dashboard(w,req,user)
co.RouteViewCounter.Bump3(94, cn)
}
case "/user":
switch(req.URL.Path) {
case "/user/edit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEdit(w,req,user,h)
co.RouteViewCounter.Bump3(95, cn)
case "/user/edit/password/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEditPassword(w,req,user,h)
co.RouteViewCounter.Bump3(96, cn)
case "/user/edit/password/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditPasswordSubmit(w,req,user)
co.RouteViewCounter.Bump3(97, cn)
case "/user/edit/avatar/submit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditAvatarSubmit(w,req,user)
co.RouteViewCounter.Bump3(98, cn)
case "/user/edit/avatar/revoke/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditRevokeAvatarSubmit(w,req,user)
co.RouteViewCounter.Bump3(99, cn)
case "/user/edit/username/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditUsernameSubmit(w,req,user)
co.RouteViewCounter.Bump3(100, cn)
case "/user/edit/privacy/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEditPrivacy(w,req,user,h)
co.RouteViewCounter.Bump3(101, cn)
case "/user/edit/privacy/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditPrivacySubmit(w,req,user)
co.RouteViewCounter.Bump3(102, cn)
case "/user/edit/mfa/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEditMFA(w,req,user,h)
co.RouteViewCounter.Bump3(103, cn)
case "/user/edit/mfa/setup/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEditMFASetup(w,req,user,h)
co.RouteViewCounter.Bump3(104, cn)
case "/user/edit/mfa/setup/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditMFASetupSubmit(w,req,user)
co.RouteViewCounter.Bump3(105, cn)
case "/user/edit/mfa/disable/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountEditMFADisableSubmit(w,req,user)
co.RouteViewCounter.Bump3(106, cn)
case "/user/edit/email/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountEditEmail(w,req,user,h)
co.RouteViewCounter.Bump3(107, cn)
case "/user/edit/token/":
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(108, cn)
case "/user/edit/logins/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountLogins(w,req,user,h)
co.RouteViewCounter.Bump3(109, cn)
case "/user/edit/blocked/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountBlocked(w,req,user,h)
co.RouteViewCounter.Bump3(110, cn)
case "/user/levels/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.LevelList(w,req,user,h)
co.RouteViewCounter.Bump3(111, cn)
case "/user/convos/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.Convos(w,req,user,h)
co.RouteViewCounter.Bump3(112, cn)
case "/user/convos/create/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.ConvosCreate(w,req,user,h)
co.RouteViewCounter.Bump3(113, cn)
case "/user/convo/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.Convo(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(114, cn)
case "/user/convos/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ConvosCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(115, cn)
case "/user/convo/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ConvosCreateReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(116, cn)
case "/user/convo/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ConvosDeleteReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(117, cn)
case "/user/convo/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ConvosEditReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(118, cn)
case "/user/block/create/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.RelationsBlockCreate(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(119, cn)
case "/user/block/create/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.RelationsBlockCreateSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(120, cn)
case "/user/block/remove/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.RelationsBlockRemove(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(121, cn)
case "/user/block/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.RelationsBlockRemoveSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(122, cn)
default:
req.URL.Path += extraData
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.ViewProfile(w,req,user, h)
co.RouteViewCounter.Bump3(123, cn)
}
case "/users":
switch(req.URL.Path) {
case "/users/ban/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.BanUserSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(124, cn)
case "/users/unban/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.UnbanUser(w,req,user,extraData)
co.RouteViewCounter.Bump3(125, cn)
case "/users/activate/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ActivateUser(w,req,user,extraData)
co.RouteViewCounter.Bump3(126, cn)
case "/users/ips/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.IPSearch(w,req,user,h)
co.RouteViewCounter.Bump3(127, cn)
case "/users/delete-posts/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.DeletePostsSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(128, cn)
}
case "/topic":
switch(req.URL.Path) {
case "/topic/create/submit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = routes.CreateTopicSubmit(w,req,user)
co.RouteViewCounter.Bump3(129, cn)
case "/topic/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.EditTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(130, cn)
case "/topic/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
req.URL.Path += extraData
err = routes.DeleteTopicSubmit(w,req,user)
co.RouteViewCounter.Bump3(131, cn)
case "/topic/stick/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.StickTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(132, cn)
case "/topic/unstick/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.UnstickTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(133, cn)
case "/topic/lock/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
req.URL.Path += extraData
err = routes.LockTopicSubmit(w,req,user)
co.RouteViewCounter.Bump3(134, cn)
case "/topic/unlock/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.UnlockTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(135, cn)
case "/topic/move/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.MoveTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(136, cn)
case "/topic/like/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.LikeTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(137, cn)
case "/topic/unlike/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.UnlikeTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(138, cn)
case "/topic/attach/add/submit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(139, cn)
case "/topic/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(140, cn)
default:
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.ViewTopic(w,req,user, h, extraData)
co.RouteViewCounter.Bump3(141, cn)
}
case "/reply":
switch(req.URL.Path) {
case "/reply/create/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = routes.CreateReplySubmit(w,req,user)
co.RouteViewCounter.Bump3(142, cn)
case "/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(143, cn)
case "/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(144, cn)
case "/reply/like/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyLikeSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(145, cn)
case "/reply/unlike/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyUnlikeSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(146, cn)
case "/reply/attach/add/submit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil {
return err
}
err = c.NoUploadSessionMismatch(w,req,user)
if err != nil {
return err
}
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(147, cn)
case "/reply/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(148, cn)
}
case "/profile":
switch(req.URL.Path) {
case "/profile/reply/create/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ProfileReplyCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(149, cn)
case "/profile/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(150, cn)
case "/profile/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(151, cn)
}
case "/poll":
switch(req.URL.Path) {
case "/poll/vote/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.PollVote(w,req,user,extraData)
co.RouteViewCounter.Bump3(152, cn)
case "/poll/results/":
err = routes.PollResults(w,req,user,extraData)
co.RouteViewCounter.Bump3(153, cn)
}
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountLogin(w,req,user,h)
co.RouteViewCounter.Bump3(154, cn)
case "/accounts/create/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountRegister(w,req,user,h)
co.RouteViewCounter.Bump3(155, cn)
case "/accounts/logout/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.AccountLogout(w,req,user)
co.RouteViewCounter.Bump3(156, cn)
case "/accounts/login/submit/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.AccountLoginSubmit(w,req,user)
co.RouteViewCounter.Bump3(157, cn)
case "/accounts/mfa_verify/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountLoginMFAVerify(w,req,user,h)
co.RouteViewCounter.Bump3(158, cn)
case "/accounts/mfa_verify/submit/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
co.RouteViewCounter.Bump3(159, cn)
case "/accounts/create/submit/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.AccountRegisterSubmit(w,req,user)
co.RouteViewCounter.Bump3(160, cn)
case "/accounts/password-reset/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountPasswordReset(w,req,user,h)
co.RouteViewCounter.Bump3(161, cn)
case "/accounts/password-reset/submit/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.AccountPasswordResetSubmit(w,req,user)
co.RouteViewCounter.Bump3(162, cn)
case "/accounts/password-reset/token/":
h, err := c.UserCheckNano(w,req,user,cn)
if err != nil {
return err
}
err = routes.AccountPasswordResetToken(w,req,user,h)
co.RouteViewCounter.Bump3(163, cn)
case "/accounts/password-reset/token/submit/":
err = c.ParseForm(w,req,user)
if err != nil {
return err
}
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
co.RouteViewCounter.Bump3(164, cn)
}
/*case "/sitemaps": // TODO: Count these views
req.URL.Path += extraData
err = sitemapSwitch(w,req)*/
// ! Temporary fix for certain bots
case "/static":
w.Header().Set("Connection", "close")
http.Redirect(w, req, "/s/"+extraData, http.StatusTemporaryRedirect)
case "/uploads":
if extraData == "" {
co.RouteViewCounter.Bump3(166, cn)
return c.NotFound(w,req,nil)
}
/*if bzw, ok := w.(c.BrResponseWriter); ok {
w = bzw.ResponseWriter
w.Header().Del("Content-Encoding")
} else */if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Encoding")
}
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
r.UploadHandler(w,req) // TODO: Count these views
co.RouteViewCounter.Bump3(166, cn)
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":
co.RouteViewCounter.Bump3(168, cn)
return routes.RobotsTxt(w,req)
case "favicon.ico":
/*if bzw, ok := w.(c.BrResponseWriter); ok {
w = bzw.ResponseWriter
w.Header().Del("Content-Encoding")
} else */if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter
w.Header().Del("Content-Encoding")
}
req.URL.Path = "/s/favicon.ico"
routes.StaticFile(w,req)
co.RouteViewCounter.Bump3(171, cn)
return nil
case "opensearch.xml":
co.RouteViewCounter.Bump3(170, cn)
return routes.OpenSearchXml(w,req)
/*case "sitemap.xml":
co.RouteViewCounter.Bump3(169, cn)
return routes.SitemapXml(w,req)*/
}
co.RouteViewCounter.Bump(0)
return c.NotFound(w,req,nil)
default:
// A fallback for dynamic routes, e.g. ones declared by plugins
r.RLock()
h, ok := r.extraRoutes[req.URL.Path]
r.RUnlock()
req.URL.Path += extraData
if ok {
// TODO: Be more specific about *which* dynamic route it is
co.RouteViewCounter.Bump(165)
return h(w,req,user)
}
co.RouteViewCounter.Bump3(172, cn)
lp := strings.ToLower(req.URL.Path)
if strings.Contains(lp,"admin") || strings.Contains(lp,"sql") || strings.Contains(lp,"manage") || strings.Contains(lp,"//") || strings.Contains(lp,"\\\\") || strings.Contains(lp,"wp") || strings.Contains(lp,"wordpress") || strings.Contains(lp,"config") || strings.Contains(lp,"setup") || strings.Contains(lp,"install") || strings.Contains(lp,"update") || strings.Contains(lp,"php") || strings.Contains(lp,"pl") || strings.Contains(lp,"wget") || strings.Contains(lp,"wp-") || strings.Contains(lp,"include") || strings.Contains(lp,"vendor") || strings.Contains(lp,"bin") || strings.Contains(lp,"system") || strings.Contains(lp,"eval") || strings.Contains(lp,"config") {
r.SuspiciousRequest(req,"Bad Route")
return c.MicroNotFound(w,req)
}
r.DumpRequest(req,"Bad Route")
ae := req.Header.Get("Accept-Encoding")
likelyBot := ae == "gzip" || ae == ""
if likelyBot {
return c.MicroNotFound(w,req)
}
return c.NotFound(w,req,nil)
}
return err
}