mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-25 20:51:53 +08:00
feat: add a config option to bypass mime content type sniffing (#60)
This commit is contained in:
+12
-5
@@ -122,8 +122,11 @@ func parseUsers(raw []interface{}, c *lib.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.Handler = &webdav.Handler{
|
user.Handler = &webdav.Handler{
|
||||||
Prefix: c.User.Handler.Prefix,
|
Prefix: c.User.Handler.Prefix,
|
||||||
FileSystem: webdav.Dir(user.Scope),
|
FileSystem: lib.WebDavDir{
|
||||||
|
Dir: webdav.Dir(user.Scope),
|
||||||
|
NoSniff: c.NoSniff,
|
||||||
|
},
|
||||||
LockSystem: webdav.NewMemLS(),
|
LockSystem: webdav.NewMemLS(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,12 +182,16 @@ func readConfig(flags *pflag.FlagSet) *lib.Config {
|
|||||||
Modify: getOptB(flags, "modify"),
|
Modify: getOptB(flags, "modify"),
|
||||||
Rules: []*lib.Rule{},
|
Rules: []*lib.Rule{},
|
||||||
Handler: &webdav.Handler{
|
Handler: &webdav.Handler{
|
||||||
Prefix: getOpt(flags, "prefix"),
|
Prefix: getOpt(flags, "prefix"),
|
||||||
FileSystem: webdav.Dir(getOpt(flags, "scope")),
|
FileSystem: lib.WebDavDir{
|
||||||
|
Dir: webdav.Dir(getOpt(flags, "scope")),
|
||||||
|
NoSniff: getOptB(flags, "nosniff"),
|
||||||
|
},
|
||||||
LockSystem: webdav.NewMemLS(),
|
LockSystem: webdav.NewMemLS(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Auth: getOptB(flags, "auth"),
|
Auth: getOptB(flags, "auth"),
|
||||||
|
NoSniff: getOptB(flags, "nosniff"),
|
||||||
Cors: lib.CorsCfg{
|
Cors: lib.CorsCfg{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Credentials: false,
|
Credentials: false,
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"mime"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"golang.org/x/net/webdav"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoSniffFileInfo wraps any generic FileInfo interface and bypasses mime type sniffing.
|
||||||
|
type NoSniffFileInfo struct {
|
||||||
|
os.FileInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w NoSniffFileInfo) ContentType(ctx context.Context) (contentType string, err error) {
|
||||||
|
if mimeType := mime.TypeByExtension(path.Ext(w.FileInfo.Name())); mimeType != "" {
|
||||||
|
// We can figure out the mime from the extension.
|
||||||
|
return mimeType, nil
|
||||||
|
} else {
|
||||||
|
// We can't figure out the mime type without sniffing, call it an octet stream.
|
||||||
|
return "application/octet-stream", nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebDavDir struct {
|
||||||
|
webdav.Dir
|
||||||
|
NoSniff bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d WebDavDir) Stat(ctx context.Context, name string) (os.FileInfo, error) {
|
||||||
|
// Skip wrapping if NoSniff is off
|
||||||
|
if !d.NoSniff {
|
||||||
|
return d.Dir.Stat(ctx, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := d.Dir.Stat(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoSniffFileInfo{info}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d WebDavDir) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
|
||||||
|
// Skip wrapping if NoSniff is off
|
||||||
|
if !d.NoSniff {
|
||||||
|
return d.Dir.OpenFile(ctx, name, flag, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := d.Dir.OpenFile(ctx, name, flag, perm)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return WebDavFile{File: file}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebDavFile struct {
|
||||||
|
webdav.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f WebDavFile) Stat() (os.FileInfo, error) {
|
||||||
|
info, err := f.File.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoSniffFileInfo{info}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f WebDavFile) Readdir(count int) (fis []os.FileInfo, err error) {
|
||||||
|
fis, err = f.File.Readdir(count)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range fis {
|
||||||
|
fis[i] = NoSniffFileInfo{fis[i]}
|
||||||
|
}
|
||||||
|
return fis, nil
|
||||||
|
}
|
||||||
+4
-3
@@ -20,9 +20,10 @@ type CorsCfg struct {
|
|||||||
// Config is the configuration of a WebDAV instance.
|
// Config is the configuration of a WebDAV instance.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
*User
|
*User
|
||||||
Auth bool
|
Auth bool
|
||||||
Cors CorsCfg
|
NoSniff bool
|
||||||
Users map[string]*User
|
Cors CorsCfg
|
||||||
|
Users map[string]*User
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
|
// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
|
||||||
|
|||||||
Reference in New Issue
Block a user