// 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 ( "strings" //"bytes" "strconv" "compress/gzip" "sync/atomic" "errors" "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.TopicListWeekViews": routes.TopicListWeekViews, "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.ForumsEditActionCreateSubmit": panel.ForumsEditActionCreateSubmit, "panel.ForumsEditActionDeleteSubmit": panel.ForumsEditActionDeleteSubmit, "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.DebugTasks": panel.DebugTasks, "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.TopicListWeekViews": 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.ForumsEditActionCreateSubmit": 27, "panel.ForumsEditActionDeleteSubmit": 28, "panel.Settings": 29, "panel.SettingEdit": 30, "panel.SettingEditSubmit": 31, "panel.WordFilters": 32, "panel.WordFiltersCreateSubmit": 33, "panel.WordFiltersEdit": 34, "panel.WordFiltersEditSubmit": 35, "panel.WordFiltersDeleteSubmit": 36, "panel.Pages": 37, "panel.PagesCreateSubmit": 38, "panel.PagesEdit": 39, "panel.PagesEditSubmit": 40, "panel.PagesDeleteSubmit": 41, "panel.Themes": 42, "panel.ThemesSetDefault": 43, "panel.ThemesMenus": 44, "panel.ThemesMenusEdit": 45, "panel.ThemesMenuItemEdit": 46, "panel.ThemesMenuItemEditSubmit": 47, "panel.ThemesMenuItemCreateSubmit": 48, "panel.ThemesMenuItemDeleteSubmit": 49, "panel.ThemesMenuItemOrderSubmit": 50, "panel.ThemesWidgets": 51, "panel.ThemesWidgetsEditSubmit": 52, "panel.ThemesWidgetsCreateSubmit": 53, "panel.ThemesWidgetsDeleteSubmit": 54, "panel.Plugins": 55, "panel.PluginsActivate": 56, "panel.PluginsDeactivate": 57, "panel.PluginsInstall": 58, "panel.Users": 59, "panel.UsersEdit": 60, "panel.UsersEditSubmit": 61, "panel.UsersAvatarSubmit": 62, "panel.UsersAvatarRemoveSubmit": 63, "panel.AnalyticsViews": 64, "panel.AnalyticsRoutes": 65, "panel.AnalyticsRoutesPerf": 66, "panel.AnalyticsAgents": 67, "panel.AnalyticsSystems": 68, "panel.AnalyticsLanguages": 69, "panel.AnalyticsReferrers": 70, "panel.AnalyticsRouteViews": 71, "panel.AnalyticsAgentViews": 72, "panel.AnalyticsForumViews": 73, "panel.AnalyticsSystemViews": 74, "panel.AnalyticsLanguageViews": 75, "panel.AnalyticsReferrerViews": 76, "panel.AnalyticsPosts": 77, "panel.AnalyticsMemory": 78, "panel.AnalyticsActiveMemory": 79, "panel.AnalyticsTopics": 80, "panel.AnalyticsForums": 81, "panel.AnalyticsPerf": 82, "panel.Groups": 83, "panel.GroupsEdit": 84, "panel.GroupsEditPromotions": 85, "panel.GroupsPromotionsCreateSubmit": 86, "panel.GroupsPromotionsDeleteSubmit": 87, "panel.GroupsEditPerms": 88, "panel.GroupsEditSubmit": 89, "panel.GroupsEditPermsSubmit": 90, "panel.GroupsCreateSubmit": 91, "panel.Backups": 92, "panel.LogsRegs": 93, "panel.LogsMod": 94, "panel.LogsAdmin": 95, "panel.Debug": 96, "panel.DebugTasks": 97, "panel.Dashboard": 98, "routes.AccountEdit": 99, "routes.AccountEditPassword": 100, "routes.AccountEditPasswordSubmit": 101, "routes.AccountEditAvatarSubmit": 102, "routes.AccountEditRevokeAvatarSubmit": 103, "routes.AccountEditUsernameSubmit": 104, "routes.AccountEditPrivacy": 105, "routes.AccountEditPrivacySubmit": 106, "routes.AccountEditMFA": 107, "routes.AccountEditMFASetup": 108, "routes.AccountEditMFASetupSubmit": 109, "routes.AccountEditMFADisableSubmit": 110, "routes.AccountEditEmail": 111, "routes.AccountEditEmailTokenSubmit": 112, "routes.AccountLogins": 113, "routes.AccountBlocked": 114, "routes.LevelList": 115, "routes.Convos": 116, "routes.ConvosCreate": 117, "routes.Convo": 118, "routes.ConvosCreateSubmit": 119, "routes.ConvosCreateReplySubmit": 120, "routes.ConvosDeleteReplySubmit": 121, "routes.ConvosEditReplySubmit": 122, "routes.RelationsBlockCreate": 123, "routes.RelationsBlockCreateSubmit": 124, "routes.RelationsBlockRemove": 125, "routes.RelationsBlockRemoveSubmit": 126, "routes.ViewProfile": 127, "routes.BanUserSubmit": 128, "routes.UnbanUser": 129, "routes.ActivateUser": 130, "routes.IPSearch": 131, "routes.DeletePostsSubmit": 132, "routes.CreateTopicSubmit": 133, "routes.EditTopicSubmit": 134, "routes.DeleteTopicSubmit": 135, "routes.StickTopicSubmit": 136, "routes.UnstickTopicSubmit": 137, "routes.LockTopicSubmit": 138, "routes.UnlockTopicSubmit": 139, "routes.MoveTopicSubmit": 140, "routes.LikeTopicSubmit": 141, "routes.UnlikeTopicSubmit": 142, "routes.AddAttachToTopicSubmit": 143, "routes.RemoveAttachFromTopicSubmit": 144, "routes.ViewTopic": 145, "routes.CreateReplySubmit": 146, "routes.ReplyEditSubmit": 147, "routes.ReplyDeleteSubmit": 148, "routes.ReplyLikeSubmit": 149, "routes.ReplyUnlikeSubmit": 150, "routes.AddAttachToReplySubmit": 151, "routes.RemoveAttachFromReplySubmit": 152, "routes.ProfileReplyCreateSubmit": 153, "routes.ProfileReplyEditSubmit": 154, "routes.ProfileReplyDeleteSubmit": 155, "routes.PollVote": 156, "routes.PollResults": 157, "routes.AccountLogin": 158, "routes.AccountRegister": 159, "routes.AccountLogout": 160, "routes.AccountLoginSubmit": 161, "routes.AccountLoginMFAVerify": 162, "routes.AccountLoginMFAVerifySubmit": 163, "routes.AccountRegisterSubmit": 164, "routes.AccountPasswordReset": 165, "routes.AccountPasswordResetSubmit": 166, "routes.AccountPasswordResetToken": 167, "routes.AccountPasswordResetTokenSubmit": 168, "routes.DynamicRoute": 169, "routes.UploadedFile": 170, "routes.StaticFile": 171, "routes.RobotsTxt": 172, "routes.SitemapXml": 173, "routes.OpenSearchXml": 174, "routes.Favicon": 175, "routes.BadRoute": 176, "routes.HTTPSRedirect": 177, } 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.TopicListWeekViews", 15: "routes.CreateTopic", 16: "routes.TopicList", 17: "panel.Forums", 18: "panel.ForumsCreateSubmit", 19: "panel.ForumsDelete", 20: "panel.ForumsDeleteSubmit", 21: "panel.ForumsOrderSubmit", 22: "panel.ForumsEdit", 23: "panel.ForumsEditSubmit", 24: "panel.ForumsEditPermsSubmit", 25: "panel.ForumsEditPermsAdvance", 26: "panel.ForumsEditPermsAdvanceSubmit", 27: "panel.ForumsEditActionCreateSubmit", 28: "panel.ForumsEditActionDeleteSubmit", 29: "panel.Settings", 30: "panel.SettingEdit", 31: "panel.SettingEditSubmit", 32: "panel.WordFilters", 33: "panel.WordFiltersCreateSubmit", 34: "panel.WordFiltersEdit", 35: "panel.WordFiltersEditSubmit", 36: "panel.WordFiltersDeleteSubmit", 37: "panel.Pages", 38: "panel.PagesCreateSubmit", 39: "panel.PagesEdit", 40: "panel.PagesEditSubmit", 41: "panel.PagesDeleteSubmit", 42: "panel.Themes", 43: "panel.ThemesSetDefault", 44: "panel.ThemesMenus", 45: "panel.ThemesMenusEdit", 46: "panel.ThemesMenuItemEdit", 47: "panel.ThemesMenuItemEditSubmit", 48: "panel.ThemesMenuItemCreateSubmit", 49: "panel.ThemesMenuItemDeleteSubmit", 50: "panel.ThemesMenuItemOrderSubmit", 51: "panel.ThemesWidgets", 52: "panel.ThemesWidgetsEditSubmit", 53: "panel.ThemesWidgetsCreateSubmit", 54: "panel.ThemesWidgetsDeleteSubmit", 55: "panel.Plugins", 56: "panel.PluginsActivate", 57: "panel.PluginsDeactivate", 58: "panel.PluginsInstall", 59: "panel.Users", 60: "panel.UsersEdit", 61: "panel.UsersEditSubmit", 62: "panel.UsersAvatarSubmit", 63: "panel.UsersAvatarRemoveSubmit", 64: "panel.AnalyticsViews", 65: "panel.AnalyticsRoutes", 66: "panel.AnalyticsRoutesPerf", 67: "panel.AnalyticsAgents", 68: "panel.AnalyticsSystems", 69: "panel.AnalyticsLanguages", 70: "panel.AnalyticsReferrers", 71: "panel.AnalyticsRouteViews", 72: "panel.AnalyticsAgentViews", 73: "panel.AnalyticsForumViews", 74: "panel.AnalyticsSystemViews", 75: "panel.AnalyticsLanguageViews", 76: "panel.AnalyticsReferrerViews", 77: "panel.AnalyticsPosts", 78: "panel.AnalyticsMemory", 79: "panel.AnalyticsActiveMemory", 80: "panel.AnalyticsTopics", 81: "panel.AnalyticsForums", 82: "panel.AnalyticsPerf", 83: "panel.Groups", 84: "panel.GroupsEdit", 85: "panel.GroupsEditPromotions", 86: "panel.GroupsPromotionsCreateSubmit", 87: "panel.GroupsPromotionsDeleteSubmit", 88: "panel.GroupsEditPerms", 89: "panel.GroupsEditSubmit", 90: "panel.GroupsEditPermsSubmit", 91: "panel.GroupsCreateSubmit", 92: "panel.Backups", 93: "panel.LogsRegs", 94: "panel.LogsMod", 95: "panel.LogsAdmin", 96: "panel.Debug", 97: "panel.DebugTasks", 98: "panel.Dashboard", 99: "routes.AccountEdit", 100: "routes.AccountEditPassword", 101: "routes.AccountEditPasswordSubmit", 102: "routes.AccountEditAvatarSubmit", 103: "routes.AccountEditRevokeAvatarSubmit", 104: "routes.AccountEditUsernameSubmit", 105: "routes.AccountEditPrivacy", 106: "routes.AccountEditPrivacySubmit", 107: "routes.AccountEditMFA", 108: "routes.AccountEditMFASetup", 109: "routes.AccountEditMFASetupSubmit", 110: "routes.AccountEditMFADisableSubmit", 111: "routes.AccountEditEmail", 112: "routes.AccountEditEmailTokenSubmit", 113: "routes.AccountLogins", 114: "routes.AccountBlocked", 115: "routes.LevelList", 116: "routes.Convos", 117: "routes.ConvosCreate", 118: "routes.Convo", 119: "routes.ConvosCreateSubmit", 120: "routes.ConvosCreateReplySubmit", 121: "routes.ConvosDeleteReplySubmit", 122: "routes.ConvosEditReplySubmit", 123: "routes.RelationsBlockCreate", 124: "routes.RelationsBlockCreateSubmit", 125: "routes.RelationsBlockRemove", 126: "routes.RelationsBlockRemoveSubmit", 127: "routes.ViewProfile", 128: "routes.BanUserSubmit", 129: "routes.UnbanUser", 130: "routes.ActivateUser", 131: "routes.IPSearch", 132: "routes.DeletePostsSubmit", 133: "routes.CreateTopicSubmit", 134: "routes.EditTopicSubmit", 135: "routes.DeleteTopicSubmit", 136: "routes.StickTopicSubmit", 137: "routes.UnstickTopicSubmit", 138: "routes.LockTopicSubmit", 139: "routes.UnlockTopicSubmit", 140: "routes.MoveTopicSubmit", 141: "routes.LikeTopicSubmit", 142: "routes.UnlikeTopicSubmit", 143: "routes.AddAttachToTopicSubmit", 144: "routes.RemoveAttachFromTopicSubmit", 145: "routes.ViewTopic", 146: "routes.CreateReplySubmit", 147: "routes.ReplyEditSubmit", 148: "routes.ReplyDeleteSubmit", 149: "routes.ReplyLikeSubmit", 150: "routes.ReplyUnlikeSubmit", 151: "routes.AddAttachToReplySubmit", 152: "routes.RemoveAttachFromReplySubmit", 153: "routes.ProfileReplyCreateSubmit", 154: "routes.ProfileReplyEditSubmit", 155: "routes.ProfileReplyDeleteSubmit", 156: "routes.PollVote", 157: "routes.PollResults", 158: "routes.AccountLogin", 159: "routes.AccountRegister", 160: "routes.AccountLogout", 161: "routes.AccountLoginSubmit", 162: "routes.AccountLoginMFAVerify", 163: "routes.AccountLoginMFAVerifySubmit", 164: "routes.AccountRegisterSubmit", 165: "routes.AccountPasswordReset", 166: "routes.AccountPasswordResetSubmit", 167: "routes.AccountPasswordResetToken", 168: "routes.AccountPasswordResetTokenSubmit", 169: "routes.DynamicRoute", 170: "routes.UploadedFile", 171: "routes.StaticFile", 172: "routes.RobotsTxt", 173: "routes.SitemapXml", 174: "routes.OpenSearchXml", 175: "routes.Favicon", 176: "routes.BadRoute", 177: "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, "opera": 1, "chrome": 2, "firefox": 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, "qwant": 19, "datenbank": 20, "baidu": 21, "sogou": 22, "toutiao": 23, "haosou": 24, "duckduckgo": 25, "seznambot": 26, "discord": 27, "telegram": 28, "twitter": 29, "facebook": 30, "cloudflare": 31, "archive_org": 32, "uptimebot": 33, "slackbot": 34, "apple": 35, "discourse": 36, "xenforo": 37, "mattermost": 38, "alexa": 39, "lynx": 40, "blank": 41, "malformed": 42, "suspicious": 43, "semrush": 44, "dotbot": 45, "ahrefs": 46, "proximic": 47, "megaindex": 48, "majestic": 49, "cocolyze": 50, "babbar": 51, "surdotly": 52, "domcop": 53, "netcraft": 54, "seostar": 55, "pandalytics": 56, "blexbot": 57, "wappalyzer": 58, "twingly": 59, "linkfluence": 60, "pagething": 61, "burf": 62, "aspiegel": 63, "mail_ru": 64, "ccbot": 65, "yacy": 66, "zgrab": 67, "cloudsystemnetworks": 68, "maui": 69, "curl": 70, "python": 71, "headlesschrome": 72, "awesome_bot": 73, } var reverseAgentMapEnum = map[int]string{ 0: "unknown", 1: "opera", 2: "chrome", 3: "firefox", 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: "qwant", 20: "datenbank", 21: "baidu", 22: "sogou", 23: "toutiao", 24: "haosou", 25: "duckduckgo", 26: "seznambot", 27: "discord", 28: "telegram", 29: "twitter", 30: "facebook", 31: "cloudflare", 32: "archive_org", 33: "uptimebot", 34: "slackbot", 35: "apple", 36: "discourse", 37: "xenforo", 38: "mattermost", 39: "alexa", 40: "lynx", 41: "blank", 42: "malformed", 43: "suspicious", 44: "semrush", 45: "dotbot", 46: "ahrefs", 47: "proximic", 48: "megaindex", 49: "majestic", 50: "cocolyze", 51: "babbar", 52: "surdotly", 53: "domcop", 54: "netcraft", 55: "seostar", 56: "pandalytics", 57: "blexbot", 58: "wappalyzer", 59: "twingly", 60: "linkfluence", 61: "pagething", 62: "burf", 63: "aspiegel", 64: "mail_ru", 65: "ccbot", 66: "yacy", 67: "zgrab", 68: "cloudsystemnetworks", 69: "maui", 70: "curl", 71: "python", 72: "headlesschrome", 73: "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", "Bytespider": "toutiao", "360Spider": "haosou", "bingbot": "bing", "BingPreview": "bing", "msnbot": "bing", "Slurp": "slurp", "Exabot": "exabot", "MojeekBot": "mojeek", "Cliqzbot": "cliqz", "Qwantify": "qwant", "netEstate": "datenbank", "SeznamBot": "seznambot", "CloudFlare": "cloudflare", "archive": "archive_org", "Uptimebot": "uptimebot", "Slackbot": "slackbot", "Slack": "slackbot", "Discordbot": "discord", "TelegramBot": "telegram", "Twitterbot": "twitter", "facebookexternalhit": "facebook", "Facebot": "facebook", "Applebot": "apple", "Discourse": "discourse", "XenForo": "xenforo", "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", "DomCopBot": "domcop", "NetcraftSurveyAgent": "netcraft", "seostar": "seostar", "Pandalytics": "pandalytics", "BLEXBot": "blexbot", "Wappalyzer": "wappalyzer", "Twingly": "twingly", "linkfluence": "linkfluence", "PageThing": "pagething", "Burf": "burf", "AspiegelBot": "aspiegel", "PetalBot": "aspiegel", "RU_Bot": "mail_ru", "CCBot": "ccbot", "yacybot": "yacy", "zgrab": "zgrab", "Nimbostratus": "cloudsystemnetworks", "MauiBot": "maui", "curl": "curl", "python": "python", "HeadlessChrome": "headlesschrome", "awesome_bot": "awesome_bot", } var markToID = map[string]int{ "OPR": 1, "Chrome": 2, "Firefox": 3, "Safari": 4, "MSIE": 6, "Trident": 7, "Edge": 5, "Lynx": 40, "SamsungBrowser": 10, "UCBrowser": 11, "Google": 12, "Googlebot": 12, "yandex": 13, "DuckDuckBot": 25, "DuckDuckGo": 25, "Baiduspider": 21, "Sogou": 22, "ToutiaoSpider": 23, "Bytespider": 23, "360Spider": 24, "bingbot": 14, "BingPreview": 14, "msnbot": 14, "Slurp": 15, "Exabot": 16, "MojeekBot": 17, "Cliqzbot": 18, "Qwantify": 19, "netEstate": 20, "SeznamBot": 26, "CloudFlare": 31, "archive": 32, "Uptimebot": 33, "Slackbot": 34, "Slack": 34, "Discordbot": 27, "TelegramBot": 28, "Twitterbot": 29, "facebookexternalhit": 30, "Facebot": 30, "Applebot": 35, "Discourse": 36, "XenForo": 37, "mattermost": 38, "ia_archiver": 39, "SemrushBot": 44, "DotBot": 45, "AhrefsBot": 46, "proximic": 47, "MegaIndex": 48, "MJ12bot": 49, "mj12bot": 49, "Cocolyzebot": 50, "Barkrowler": 51, "SurdotlyBot": 52, "DomCopBot": 53, "NetcraftSurveyAgent": 54, "seostar": 55, "Pandalytics": 56, "BLEXBot": 57, "Wappalyzer": 58, "Twingly": 59, "linkfluence": 60, "PageThing": 61, "Burf": 62, "AspiegelBot": 63, "PetalBot": 63, "RU_Bot": 64, "CCBot": 65, "yacybot": 66, "zgrab": 67, "Nimbostratus": 68, "MauiBot": 69, "curl": 70, "python": 71, "HeadlessChrome": 72, "awesome_bot": 73, } /*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) g := func(n string) int { a, ok := agentMapEnum[n] if !ok { panic("name not found in agentMapEnum") } return a } c.Chrome = g("chrome") c.Firefox = g("firefox") c.SimpleBots = []int{ g("semrush"), g("ahrefs"), g("python"), //g("go"), g("curl"), } } // 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(177) dest := "https://" + req.Host + req.URL.String() http.Redirect(w, req, dest, http.StatusTemporaryRedirect) } func (r *GenRouter) SuspiciousRequest(req *http.Request, pre string) { if c.Config.DisableSuspLog { return } var sb strings.Builder if pre != "" { sb.WriteString("Suspicious Request\n") } else { pre = "Suspicious Request" } r.ddumpRequest(req,pre,r.suspLog,&sb) co.AgentViewCounter.Bump(43) } // 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(42) } // 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, p string if c.Config.SslSchema { s = "s" } 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 } r.suspScan(req) // 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(171) } 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.reqLogger.Print("before PreRoute") } /*if c.Dev.QuicPort != 0 { sQuicPort := strconv.Itoa(c.Dev.QuicPort) w.Header().Set("Alt-Svc", "quic=\":"+sQuicPort+"\"; ma=2592000; v=\"44,43,39\", h3-23=\":"+sQuicPort+"\"; ma=3600, h3-24=\":"+sQuicPort+"\"; 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 // TODO: Make this testable 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(41) r.unknownUA(req) } 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 > 47 && it < 58) || it == '_' { // TODO: Store an index and slice that instead? buf = append(buf, it) } else if it == ' ' || it == '(' || it == ')' || it == '-' || it == ';' || it == ':' || it == '.' || it == '+' || it == '~' || it == '@' /*|| (it == ':' && bytes.Equal(buf,[]byte("http")))*/ || it == ',' || it == '/' { //log.Print("buf: ",string(buf)) //log.Print("it: ",string(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","com","KHTML": // Skip these words default: //log.Print("append buf") items = append(items, string(buf)) } } //log.Print("reset buf") buf = buf[:0] } } else { // TODO: Test this items = items[:0] if c.Config.DisableSuspLog { r.reqLogger.Print("Illegal char "+strconv.Itoa(int(it))+" in UA\nUA Buf: ", buf,"\nUA Buf String: ", string(buf)) } else { r.SuspiciousRequest(req,"Illegal char "+strconv.Itoa(int(it))+" in UA") r.reqLogger.Print("UA Buf: ", buf,"\nUA 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.reqLogger.Print("parsed agent: ", agent,"\nos: ", os) r.reqLogger.Printf("items: %+v\n",items) /*for _, it := range items { r.reqLogger.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 67: w.WriteHeader(200) // 400 w.Write([]byte("")) r.DumpRequest(req,"Blocked Scanner") co.AgentViewCounter.Bump(67) return } if agent == 0 { //co.AgentViewCounter.Bump(0) r.unknownUA(req) }// 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 // TODO: Extend the effects of DNT elsewhere? if ref != "" && req.Header.Get("DNT") != "1" { // ? 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.reqLogger.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 } w = r.responseWriter(w) 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 } err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = c.MemberOnly(w,req,user) if err != nil { return err } switch(req.URL.Path) { case "/report/submit/": 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/week-views/": h, err := c.UserCheckNano(w,req,user,cn) if err != nil { return err } err = routes.TopicListWeekViews(w,req,user,h) co.RouteViewCounter.Bump3(14, 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(15, 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(16, 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(17, 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(18, 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(19, 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(20, 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(21, cn) case "/panel/forums/edit/": err = panel.ForumsEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(22, 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(23, 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(24, cn) case "/panel/forums/edit/perms/": err = panel.ForumsEditPermsAdvance(w,req,user,extraData) co.RouteViewCounter.Bump3(25, 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(26, cn) case "/panel/forums/action/create/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = panel.ForumsEditActionCreateSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(27, cn) case "/panel/forums/action/delete/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = panel.ForumsEditActionDeleteSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(28, cn) case "/panel/settings/": err = panel.Settings(w,req,user) co.RouteViewCounter.Bump3(29, cn) case "/panel/settings/edit/": err = panel.SettingEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(30, 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(31, cn) case "/panel/settings/word-filters/": err = panel.WordFilters(w,req,user) co.RouteViewCounter.Bump3(32, 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(33, cn) case "/panel/settings/word-filters/edit/": err = panel.WordFiltersEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(34, 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(35, 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(36, cn) case "/panel/pages/": err = c.AdminOnly(w,req,user) if err != nil { return err } err = panel.Pages(w,req,user) co.RouteViewCounter.Bump3(37, 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(38, 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(39, 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(40, 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(41, cn) case "/panel/themes/": err = panel.Themes(w,req,user) co.RouteViewCounter.Bump3(42, 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(43, cn) case "/panel/themes/menus/": err = panel.ThemesMenus(w,req,user) co.RouteViewCounter.Bump3(44, cn) case "/panel/themes/menus/edit/": err = panel.ThemesMenusEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(45, cn) case "/panel/themes/menus/item/edit/": err = panel.ThemesMenuItemEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(46, 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(47, 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(48, 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(49, 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(50, cn) case "/panel/themes/widgets/": err = panel.ThemesWidgets(w,req,user) co.RouteViewCounter.Bump3(51, 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(52, 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(53, 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(54, cn) case "/panel/plugins/": err = panel.Plugins(w,req,user) co.RouteViewCounter.Bump3(55, 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(56, 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(57, 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(58, cn) case "/panel/users/": err = panel.Users(w,req,user) co.RouteViewCounter.Bump3(59, cn) case "/panel/users/edit/": err = panel.UsersEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(60, 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(61, 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(62, 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(63, 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(64, 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(65, 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(66, 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(67, 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(68, 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(69, 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(70, cn) case "/panel/analytics/route/": err = panel.AnalyticsRouteViews(w,req,user,extraData) co.RouteViewCounter.Bump3(71, cn) case "/panel/analytics/agent/": err = panel.AnalyticsAgentViews(w,req,user,extraData) co.RouteViewCounter.Bump3(72, cn) case "/panel/analytics/forum/": err = panel.AnalyticsForumViews(w,req,user,extraData) co.RouteViewCounter.Bump3(73, cn) case "/panel/analytics/system/": err = panel.AnalyticsSystemViews(w,req,user,extraData) co.RouteViewCounter.Bump3(74, cn) case "/panel/analytics/lang/": err = panel.AnalyticsLanguageViews(w,req,user,extraData) co.RouteViewCounter.Bump3(75, cn) case "/panel/analytics/referrer/": err = panel.AnalyticsReferrerViews(w,req,user,extraData) co.RouteViewCounter.Bump3(76, 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(77, 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(78, 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(79, 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(80, 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(81, 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(82, cn) case "/panel/groups/": err = panel.Groups(w,req,user) co.RouteViewCounter.Bump3(83, cn) case "/panel/groups/edit/": err = panel.GroupsEdit(w,req,user,extraData) co.RouteViewCounter.Bump3(84, cn) case "/panel/groups/edit/promotions/": err = panel.GroupsEditPromotions(w,req,user,extraData) co.RouteViewCounter.Bump3(85, 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(86, 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(87, cn) case "/panel/groups/edit/perms/": err = panel.GroupsEditPerms(w,req,user,extraData) co.RouteViewCounter.Bump3(88, 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(89, 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(90, 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(91, cn) case "/panel/backups/": err = c.SuperAdminOnly(w,req,user) if err != nil { return err } w = r.responseWriter(w) err = panel.Backups(w,req,user,extraData) co.RouteViewCounter.Bump3(92, cn) case "/panel/logs/regs/": err = panel.LogsRegs(w,req,user) co.RouteViewCounter.Bump3(93, cn) case "/panel/logs/mod/": err = panel.LogsMod(w,req,user) co.RouteViewCounter.Bump3(94, cn) case "/panel/logs/admin/": err = panel.LogsAdmin(w,req,user) co.RouteViewCounter.Bump3(95, cn) case "/panel/debug/": err = c.AdminOnly(w,req,user) if err != nil { return err } err = panel.Debug(w,req,user) co.RouteViewCounter.Bump3(96, cn) case "/panel/debug/tasks/": err = c.AdminOnly(w,req,user) if err != nil { return err } err = panel.DebugTasks(w,req,user) co.RouteViewCounter.Bump3(97, cn) default: err = panel.Dashboard(w,req,user) co.RouteViewCounter.Bump3(98, 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(99, 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(100, 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(101, 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(102, 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(103, 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(104, 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(105, 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(106, 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(107, 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(108, 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(109, 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(110, 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(111, cn) case "/user/edit/token/": err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(112, 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(113, 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(114, 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(115, 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(116, 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(117, 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(118, 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(119, 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(120, 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(121, 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(122, 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(123, 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(124, 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(125, 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(126, 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(127, cn) } case "/users": err = c.MemberOnly(w,req,user) if err != nil { return err } switch(req.URL.Path) { case "/users/ban/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.BanUserSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(128, cn) case "/users/unban/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.UnbanUser(w,req,user,extraData) co.RouteViewCounter.Bump3(129, cn) case "/users/activate/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.ActivateUser(w,req,user,extraData) co.RouteViewCounter.Bump3(130, cn) case "/users/ips/": h, err := c.UserCheckNano(w,req,user,cn) if err != nil { return err } err = routes.IPSearch(w,req,user,h) co.RouteViewCounter.Bump3(131, cn) case "/users/delete-posts/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.DeletePostsSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(132, 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(133, 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(134, 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(135, 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(136, 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(137, 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(138, 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(139, 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(140, 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(141, 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(142, 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(143, 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(144, 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(145, cn) } case "/reply": err = c.MemberOnly(w,req,user) if err != nil { return err } switch(req.URL.Path) { case "/reply/create/": 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(146, cn) case "/reply/edit/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.ReplyEditSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(147, cn) case "/reply/delete/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.ReplyDeleteSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(148, cn) case "/reply/like/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.ReplyLikeSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(149, cn) case "/reply/unlike/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.ReplyUnlikeSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(150, cn) case "/reply/attach/add/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 = routes.AddAttachToReplySubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(151, cn) case "/reply/attach/remove/submit/": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(152, cn) } case "/profile": err = c.NoSessionMismatch(w,req,user) if err != nil { return err } err = c.MemberOnly(w,req,user) if err != nil { return err } switch(req.URL.Path) { case "/profile/reply/create/": err = routes.ProfileReplyCreateSubmit(w,req,user) co.RouteViewCounter.Bump3(153, cn) case "/profile/reply/edit/submit/": err = routes.ProfileReplyEditSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(154, cn) case "/profile/reply/delete/submit/": err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData) co.RouteViewCounter.Bump3(155, 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(156, cn) case "/poll/results/": err = routes.PollResults(w,req,user,extraData) co.RouteViewCounter.Bump3(157, 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(158, 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(159, 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(160, 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(161, 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(162, 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(163, 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(164, 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(165, 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(166, 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(167, 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(168, 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(170, cn) return c.NotFound(w,req,nil) } w = r.responseWriter(w) 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(170, 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(172, cn) return routes.RobotsTxt(w,req) case "favicon.ico": w = r.responseWriter(w) req.URL.Path = "/s/favicon.ico" co.RouteViewCounter.Bump3(175, cn) routes.StaticFile(w,req) return nil case "opensearch.xml": co.RouteViewCounter.Bump3(174, cn) return routes.OpenSearchXml(w,req) /*case "sitemap.xml": co.RouteViewCounter.Bump3(173, 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(169) return h(w,req,user) } co.RouteViewCounter.Bump3(176, cn) if !c.Config.DisableSuspLog { lp := strings.ToLower(req.URL.Path) if strings.Contains(lp,"w") { if strings.Contains(lp,"wp") || strings.Contains(lp,"wordpress") || strings.Contains(lp,"wget") || strings.Contains(lp,"wp-") { r.SuspiciousRequest(req,"Bad Route") return c.MicroNotFound(w,req) } } if strings.Contains(lp,"admin") || strings.Contains(lp,"sql") || strings.Contains(lp,"manage") || strings.Contains(lp,"//") || strings.Contains(lp,"\\\\") || 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,"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) } } if !c.Config.DisableBadRouteLog { 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 }