diff options
author | Valery Piashchynski <[email protected]> | 2021-04-28 14:10:27 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-04-28 14:10:27 +0300 |
commit | 30c25f17fa7d6386e33a4894c812f7ca5db990ad (patch) | |
tree | 03f53535addf71a81eca4b9a1d3ba29d4ebf4984 /plugins/http/static/static.go | |
parent | 4cb2247f909d02c922edb6f8e3d3741cc5a2c077 (diff) |
- Fix middleware order
- Update tests
- Move worker handler into a separate folder with separate package name
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'plugins/http/static/static.go')
-rw-r--r-- | plugins/http/static/static.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/plugins/http/static/static.go b/plugins/http/static/static.go new file mode 100644 index 00000000..d0278466 --- /dev/null +++ b/plugins/http/static/static.go @@ -0,0 +1,88 @@ +package static + +import ( + "io/fs" + "net/http" + "path/filepath" + "strings" + + httpConfig "github.com/spiral/roadrunner/v2/plugins/http/config" +) + +type ExtensionFilter struct { + allowed map[string]struct{} + forbidden map[string]struct{} +} + +func NewExtensionFilter(allow, forbid []string) *ExtensionFilter { + ef := &ExtensionFilter{ + allowed: make(map[string]struct{}, len(allow)), + forbidden: make(map[string]struct{}, len(forbid)), + } + + for i := 0; i < len(forbid); i++ { + // skip empty lines + if forbid[i] == "" { + continue + } + ef.forbidden[forbid[i]] = struct{}{} + } + + for i := 0; i < len(allow); i++ { + // skip empty lines + if allow[i] == "" { + continue + } + ef.allowed[allow[i]] = struct{}{} + } + + // check if any forbidden items presented in the allowed + // if presented, delete such items from allowed + for k := range ef.allowed { + if _, ok := ef.forbidden[k]; ok { + delete(ef.allowed, k) + } + } + + return ef +} + +type FileSystem struct { + ef *ExtensionFilter + // embedded + http.FileSystem +} + +// Open wrapper around http.FileSystem Open method, name here is the name of the +func (f FileSystem) Open(name string) (http.File, error) { + file, err := f.FileSystem.Open(name) + if err != nil { + return nil, err + } + + fstat, err := file.Stat() + if err != nil { + return nil, fs.ErrNotExist + } + + if fstat.IsDir() { + return nil, fs.ErrPermission + } + + ext := strings.ToLower(filepath.Ext(fstat.Name())) + if _, ok := f.ef.forbidden[ext]; ok { + return nil, fs.ErrPermission + } + + // if file extension is allowed, append it to the FileInfo slice + if _, ok := f.ef.allowed[ext]; ok { + return file, nil + } + + return nil, fs.ErrNotExist +} + +// FS is a constructor for the http.FileSystem +func FS(config *httpConfig.Static) http.FileSystem { + return FileSystem{NewExtensionFilter(config.Allow, config.Forbid), http.Dir(config.Dir)} +} |