apng is no longer a valid image format as we don't have the technology to optimise it.

Experimenting with systemd.

Began work on an experimental hook table implementation.
Tweaked some hook implementations to make their behaviour less ambiguous.
This commit is contained in:
Azareal 2018-08-07 14:14:28 +10:00
parent 7a66b73a62
commit f2ecb9dbf7
3 changed files with 58 additions and 14 deletions

View File

@ -42,17 +42,18 @@ type StringList []string
// ? - Should we allow users to upload .php or .go files? It could cause security issues. We could store them with a mangled extension to render them inert // ? - Should we allow users to upload .php or .go files? It could cause security issues. We could store them with a mangled extension to render them inert
// TODO: Let admins manage this from the Control Panel // TODO: Let admins manage this from the Control Panel
// apng is commented out for now, as we have no way of re-encoding it into a smaller file
var AllowedFileExts = StringList{ var AllowedFileExts = StringList{
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", /*"apng",*/ // images "png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", /*"apng",*/ // images
"txt", "xml", "json", "yaml", "toml", "ini", "md", "html", "rtf", "js", "py", "rb", "css", "scss", "less", "eqcss", "pcss", "java", "ts", "cs", "c", "cc", "cpp", "cxx", "C", "c++", "h", "hh", "hpp", "hxx", "h++", "rs", "rlib", "htaccess", "gitignore", // text "txt", "xml", "json", "yaml", "toml", "ini", "md", "html", "rtf", "js", "py", "rb", "css", "scss", "less", "eqcss", "pcss", "java", "ts", "cs", "c", "cc", "cpp", "cxx", "C", "c++", "h", "hh", "hpp", "hxx", "h++", "rs", "rlib", "htaccess", "gitignore", /*"go","php",*/ // text
"mp3", "mp4", "avi", "wmv", "webm", // video "mp3", "mp4", "avi", "wmv", "webm", // video
"otf", "woff2", "woff", "ttf", "eot", // fonts "otf", "woff2", "woff", "ttf", "eot", // fonts
} }
var ImageFileExts = StringList{ var ImageFileExts = StringList{
"png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", "apng", "png", "jpg", "jpeg", "svg", "bmp", "gif", "tif", "webp", /* "apng",*/
} }
var ArchiveFileExts = StringList{ var ArchiveFileExts = StringList{
"bz2", "zip", "gz", "7z", "tar", "cab", "bz2", "zip", "gz", "7z", "tar", "cab",

View File

@ -12,6 +12,7 @@ import (
"errors" "errors"
"log" "log"
"net/http" "net/http"
"sync/atomic"
"../query_gen/lib" "../query_gen/lib"
) )
@ -39,6 +40,28 @@ func buildPlugin(plugin *Plugin) {
plugin.Data = nil plugin.Data = nil
} }
var hookTableBox atomic.Value
// ! HookTable is a work in progress, do not use it yet
// TODO: Test how fast it is to indirect hooks off the hook table as opposed to using them normally or using an interface{} for the hooks
// TODO: Can we filter the HookTable for each request down to only hooks the request actually uses?
// TODO: Make the RunXHook functions methods on HookTable
// TODO: Have plugins update hooks on a mutex guarded map and create a copy of that map in a serial global goroutine which gets thrown in the atomic.Value
type HookTable struct {
Hooks map[string][]func(interface{}) interface{}
Vhooks map[string]func(...interface{}) interface{}
VhookSkippable map[string]func(...interface{}) (bool, RouteError)
Sshooks map[string][]func(string) string
PreRenderHooks map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool
// For future use:
messageHooks map[string][]func(Message, PageInt, ...interface{}) interface{}
}
func init() {
hookTableBox.Store(new(HookTable))
}
// Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with? // Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with?
var Hooks = map[string][]func(interface{}) interface{}{ var Hooks = map[string][]func(interface{}) interface{}{
"forums_frow_assign": nil, "forums_frow_assign": nil,
@ -153,7 +176,8 @@ var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User
"pre_render_panel_themes": nil, "pre_render_panel_themes": nil,
"pre_render_panel_modlogs": nil, "pre_render_panel_modlogs": nil,
"pre_render_error": nil, // Note: This hook isn't run for a few errors whose templates are computed at startup and reused, such as InternalError. This hook is also not available in JS mode. "pre_render_error": nil, // Note: This hook isn't run for a few errors whose templates are computed at startup and reused, such as InternalError. This hook is also not available in JS mode.
// ^-- I don't know if it's run for InternalError, but it isn't computed at startup anymore
"pre_render_security_error": nil, "pre_render_security_error": nil,
} }
@ -426,14 +450,21 @@ func InitPlugins() {
// ? - Are the following functions racey? // ? - Are the following functions racey?
func RunHook(name string, data interface{}) interface{} { func RunHook(name string, data interface{}) interface{} {
for _, hook := range Hooks[name] { hooks, ok := Hooks[name]
data = hook(data) if ok {
for _, hook := range hooks {
data = hook(data)
}
} }
return data return data
} }
func RunHookNoreturn(name string, data interface{}) { func RunHookNoreturn(name string, data interface{}) {
for _, hook := range Hooks[name] { hooks, ok := Hooks[name]
if !ok {
return
}
for _, hook := range hooks {
_ = hook(data) _ = hook(data)
} }
} }
@ -479,24 +510,33 @@ func RunTaskHook(name string) error {
// Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks // Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks
func RunSshook(name string, data string) string { func RunSshook(name string, data string) string {
for _, hook := range Sshooks[name] { ssHooks, ok := Sshooks[name]
data = hook(data) if ok {
for _, hook := range ssHooks {
data = hook(data)
}
} }
return data return data
} }
func RunPreRenderHook(name string, w http.ResponseWriter, r *http.Request, user *User, data interface{}) (halt bool) { func RunPreRenderHook(name string, w http.ResponseWriter, r *http.Request, user *User, data interface{}) (halt bool) {
// This hook runs on ALL PreRender hooks // This hook runs on ALL PreRender hooks
for _, hook := range PreRenderHooks["pre_render"] { preRenderHooks, ok := PreRenderHooks["pre_render"]
if hook(w, r, user, data) { if ok {
return true for _, hook := range preRenderHooks {
if hook(w, r, user, data) {
return true
}
} }
} }
// The actual PreRender hook // The actual PreRender hook
for _, hook := range PreRenderHooks[name] { preRenderHooks, ok = PreRenderHooks[name]
if hook(w, r, user, data) { if ok {
return true for _, hook := range preRenderHooks {
if hook(w, r, user, data) {
return true
}
} }
} }
return false return false

View File

@ -15,5 +15,8 @@ WorkingDirectory=/home/gosora
# Make sure you manually run pre-run-linux before you start the service # Make sure you manually run pre-run-linux before you start the service
ExecStart=/home/gosora/Gosora ExecStart=/home/gosora/Gosora
# Let's hope this doesn't blow up on me
ProtectSystem=full
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target