2813 lines
80 KiB
Go
2813 lines
80 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"
|
|
)
|
|
|
|
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,
|
|
"baidu": 19,
|
|
"sogou": 20,
|
|
"toutiao": 21,
|
|
"haosou": 22,
|
|
"duckduckgo": 23,
|
|
"seznambot": 24,
|
|
"discord": 25,
|
|
"twitter": 26,
|
|
"facebook": 27,
|
|
"cloudflare": 28,
|
|
"archive_org": 29,
|
|
"uptimebot": 30,
|
|
"slackbot": 31,
|
|
"apple": 32,
|
|
"discourse": 33,
|
|
"alexa": 34,
|
|
"lynx": 35,
|
|
"blank": 36,
|
|
"malformed": 37,
|
|
"suspicious": 38,
|
|
"semrush": 39,
|
|
"dotbot": 40,
|
|
"ahrefs": 41,
|
|
"proximic": 42,
|
|
"majestic": 43,
|
|
"blexbot": 44,
|
|
"aspiegel": 45,
|
|
"mail_ru": 46,
|
|
"zgrab": 47,
|
|
"curl": 48,
|
|
}
|
|
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: "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: "alexa",
|
|
35: "lynx",
|
|
36: "blank",
|
|
37: "malformed",
|
|
38: "suspicious",
|
|
39: "semrush",
|
|
40: "dotbot",
|
|
41: "ahrefs",
|
|
42: "proximic",
|
|
43: "majestic",
|
|
44: "blexbot",
|
|
45: "aspiegel",
|
|
46: "mail_ru",
|
|
47: "zgrab",
|
|
48: "curl",
|
|
}
|
|
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",
|
|
"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",
|
|
"ia_archiver": "alexa",
|
|
"SemrushBot": "semrush",
|
|
"DotBot": "dotbot",
|
|
"AhrefsBot": "ahrefs",
|
|
"proximic": "proximic",
|
|
"MJ12bot": "majestic",
|
|
"BLEXBot": "blexbot",
|
|
"AspiegelBot": "aspiegel",
|
|
"RU_Bot": "mail_ru",
|
|
"zgrab": "zgrab",
|
|
"curl": "curl",
|
|
}
|
|
var markToID = map[string]int{
|
|
"OPR": 3,
|
|
"Chrome": 2,
|
|
"Firefox": 1,
|
|
"Safari": 4,
|
|
"MSIE": 6,
|
|
"Trident": 7,
|
|
"Edge": 5,
|
|
"Lynx": 35,
|
|
"SamsungBrowser": 10,
|
|
"UCBrowser": 11,
|
|
"Google": 12,
|
|
"Googlebot": 12,
|
|
"yandex": 13,
|
|
"DuckDuckBot": 23,
|
|
"DuckDuckGo": 23,
|
|
"Baiduspider": 19,
|
|
"Sogou": 20,
|
|
"ToutiaoSpider": 21,
|
|
"360Spider": 22,
|
|
"bingbot": 14,
|
|
"BingPreview": 14,
|
|
"msnbot": 14,
|
|
"Slurp": 15,
|
|
"Exabot": 16,
|
|
"MojeekBot": 17,
|
|
"Cliqzbot": 18,
|
|
"SeznamBot": 24,
|
|
"CloudFlare": 28,
|
|
"archive": 29,
|
|
"Uptimebot": 30,
|
|
"Slackbot": 31,
|
|
"Slack": 31,
|
|
"Discordbot": 25,
|
|
"Twitterbot": 26,
|
|
"facebookexternalhit": 27,
|
|
"Facebot": 27,
|
|
"Applebot": 32,
|
|
"Discourse": 33,
|
|
"ia_archiver": 34,
|
|
"SemrushBot": 39,
|
|
"DotBot": 40,
|
|
"AhrefsBot": 41,
|
|
"proximic": 42,
|
|
"MJ12bot": 43,
|
|
"BLEXBot": 44,
|
|
"AspiegelBot": 45,
|
|
"RU_Bot": 46,
|
|
"zgrab": 47,
|
|
"curl": 48,
|
|
}
|
|
/*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"]
|
|
c.Semrush = agentMapEnum["semrush"]
|
|
c.Ahrefs = agentMapEnum["ahrefs"]
|
|
}
|
|
|
|
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, user *c.User) {
|
|
if err.Handled() {
|
|
return
|
|
}
|
|
if err.Type() == "system" {
|
|
c.InternalErrorJSQ(err, w, req, err.JSON())
|
|
return
|
|
}
|
|
c.LocalErrorJSQ(err.Error(), w, req, user, 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 += "Header '" + 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(38)
|
|
}
|
|
|
|
func isLocalHost(h string) bool {
|
|
return h=="localhost" || h=="127.0.0.1" || h=="::1"
|
|
}
|
|
|
|
// 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(37)
|
|
}
|
|
|
|
// 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 {
|
|
spl := strings.Split(req.Host,":")
|
|
if len(spl) > 2 {
|
|
malformedRequest(1)
|
|
return
|
|
}
|
|
shost = spl[0]
|
|
if len(spl)==2 {
|
|
sport = spl[1]
|
|
}
|
|
}
|
|
// 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 in path")
|
|
break
|
|
}
|
|
}
|
|
lp := strings.ToLower(req.URL.Path)
|
|
// TODO: Flag any requests which has a dot with anything but a number after that
|
|
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,".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)
|
|
|
|
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]
|
|
}
|
|
|
|
// TODO: Use the same hook table as downstream
|
|
hTbl := c.GetHookTable()
|
|
skip, ferr := hTbl.VhookSkippable("router_after_filters", w, req, prefix, extraData)
|
|
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)
|
|
}
|
|
req.URL.Path += extraData
|
|
routes.StaticFile(w, req)
|
|
return
|
|
}
|
|
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 string
|
|
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(36)
|
|
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 items []string
|
|
var buffer []byte
|
|
var os int
|
|
for _, it := range uutils.StringToBytes(ua) {
|
|
if (it > 64 && it < 91) || (it > 96 && it < 123) || it == '_' {
|
|
buffer = append(buffer, it)
|
|
} else if it == ' ' || it == '(' || it == ')' || it == '-' || (it > 47 && it < 58) || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' || (it == ':' && bytes.Equal(buffer,[]byte("http"))) || it == ',' || it == '/' {
|
|
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(uutils.BytesToString(buffer)) {
|
|
case "Windows":
|
|
os = 1
|
|
case "Linux":
|
|
os = 2
|
|
case "Mac":
|
|
os = 3
|
|
case "iPhone":
|
|
os = 5
|
|
case "Android":
|
|
os = 4
|
|
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(it))+" in UA")
|
|
r.requestLogger.Print("UA Buffer: ", buffer)
|
|
r.requestLogger.Print("UA Buffer String: ", string(buffer))
|
|
break
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// 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 47:
|
|
r.SuspiciousRequest(req,"Vulnerability 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 != "" {
|
|
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 {
|
|
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 {
|
|
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)
|
|
}
|
|
|
|
// Disable Gzip when SSL is disabled for security reasons?
|
|
if prefix != "/ws" && strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
|
h := w.Header()
|
|
h.Set("Content-Encoding", "gzip")
|
|
gzw := c.GzipResponseWriter{Writer: gzip.NewWriter(w), ResponseWriter: w}
|
|
defer func() {
|
|
if h.Get("Content-Encoding") == "gzip" && h.Get("X-I") == "" {
|
|
gzw.Writer.(*gzip.Writer).Close()
|
|
}
|
|
}()
|
|
w = gzw
|
|
}
|
|
|
|
skip, ferr = hTbl.VhookSkippable("router_pre_route", w, req, user, prefix, extraData)
|
|
if skip || ferr != nil {
|
|
r.handleError(ferr,w,req,user)
|
|
}
|
|
ferr = r.routeSwitch(w, req, user, prefix, extraData)
|
|
if ferr != nil {
|
|
r.handleError(ferr,w,req,user)
|
|
}
|
|
/*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
|
|
}
|
|
|
|
gzw, ok := w.(c.GzipResponseWriter)
|
|
if 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
|
|
}
|
|
|
|
gzw, ok := w.(c.GzipResponseWriter)
|
|
if 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)
|
|
}
|
|
gzw, ok := w.(c.GzipResponseWriter)
|
|
if ok {
|
|
w = gzw.ResponseWriter
|
|
h := w.Header()
|
|
h.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":
|
|
gzw, ok := w.(c.GzipResponseWriter)
|
|
if ok {
|
|
w = gzw.ResponseWriter
|
|
h := w.Header()
|
|
h.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()
|
|
|
|
if ok {
|
|
req.URL.Path += extraData
|
|
// TODO: Be more specific about *which* dynamic route it is
|
|
co.RouteViewCounter.Bump(165)
|
|
return h(w,req,user)
|
|
}
|
|
|
|
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")
|
|
} else {
|
|
r.DumpRequest(req,"Bad Route")
|
|
}
|
|
co.RouteViewCounter.Bump3(172, cn)
|
|
return c.NotFound(w,req,nil)
|
|
}
|
|
return err
|
|
}
|