Skip to content

Commit

Permalink
feat: allow disabling file detections by reading header (#1175)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeidiDeng authored Jan 7, 2021
1 parent 43e0d4a commit 6914063
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 67 deletions.
4 changes: 4 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func addServerFlags(flags *pflag.FlagSet) {
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
flags.Bool("disable-preview-resize", false, "disable resize of image previews")
flags.Bool("disable-exec", false, "disables Command Runner feature")
flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
}

var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -243,6 +244,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
server.ResizePreview = !disablePreviewResize

_, disableTypeDetectionByHeader := getParamB(flags, "disable-type-detection-by-header")
server.TypeDetectionByHeader = !disableTypeDetectionByHeader

_, disableExec := getParamB(flags, "disable-exec")
server.EnableExec = !disableExec

Expand Down
69 changes: 39 additions & 30 deletions files/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ type FileInfo struct {

// FileOptions are the options when getting a file info.
type FileOptions struct {
Fs afero.Fs
Path string
Modify bool
Expand bool
Checker rules.Checker
Fs afero.Fs
Path string
Modify bool
Expand bool
ReadHeader bool
Checker rules.Checker
}

// NewFileInfo creates a File object from a path and a given user. This File
Expand Down Expand Up @@ -75,13 +76,13 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {

if opts.Expand {
if file.IsDir {
if err := file.readListing(opts.Checker); err != nil { //nolint:shadow
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:shadow
return nil, err
}
return file, nil
}

err = file.detectType(opts.Modify, true)
err = file.detectType(opts.Modify, true, true)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -134,7 +135,7 @@ func (i *FileInfo) Checksum(algo string) error {

//nolint:goconst
//TODO: use constants
func (i *FileInfo) detectType(modify, saveContent bool) error {
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
if IsNamedPipe(i.Mode) {
i.Type = "blob"
return nil
Expand All @@ -143,25 +144,13 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {
// imagine the situation where a file in a dir with thousands
// of files couldn't be opened: we'd have immediately
// a 500 even though it doesn't matter. So we just log it.
reader, err := i.Fs.Open(i.Path)
if err != nil {
log.Print(err)
i.Type = "blob"
return nil
}
defer reader.Close()

buffer := make([]byte, 512)
n, err := reader.Read(buffer)
if err != nil && err != io.EOF {
log.Print(err)
i.Type = "blob"
return nil
}
var buffer []byte

mimetype := mime.TypeByExtension(i.Extension)
if mimetype == "" {
mimetype = http.DetectContentType(buffer[:n])
if mimetype == "" && readHeader {
buffer = i.readFirstBytes()
mimetype = http.DetectContentType(buffer)
}

switch {
Expand All @@ -175,10 +164,7 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {
case strings.HasPrefix(mimetype, "image"):
i.Type = "image"
return nil
case isBinary(buffer[:n], n) || i.Size > 10*1024*1024: // 10 MB
i.Type = "blob"
return nil
default:
case (strings.HasPrefix(mimetype, "text") || (len(buffer) > 0 && !isBinary(buffer))) && i.Size <= 10*1024*1024: // 10 MB

This comment has been minimized.

Copy link
@dream10201

dream10201 Feb 19, 2021

Will this affect online editing of ".json" files?

i.Type = "text"

if !modify {
Expand All @@ -194,11 +180,34 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {

i.Content = string(content)
}
return nil
default:
i.Type = "blob"
}

return nil
}

func (i *FileInfo) readFirstBytes() []byte {
reader, err := i.Fs.Open(i.Path)
if err != nil {
log.Print(err)
i.Type = "blob"
return nil
}
defer reader.Close()

buffer := make([]byte, 512)
n, err := reader.Read(buffer)
if err != nil && err != io.EOF {
log.Print(err)
i.Type = "blob"
return nil
}

return buffer[:n]
}

func (i *FileInfo) detectSubtitles() {
if i.Type != "video" {
return
Expand All @@ -215,7 +224,7 @@ func (i *FileInfo) detectSubtitles() {
}
}

func (i *FileInfo) readListing(checker rules.Checker) error {
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
afs := &afero.Afero{Fs: i.Fs}
dir, err := afs.ReadDir(i.Path)
if err != nil {
Expand Down Expand Up @@ -261,7 +270,7 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
} else {
listing.NumFiles++

err := file.detectType(true, false)
err := file.detectType(true, false, readHeader)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion files/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"unicode/utf8"
)

func isBinary(content []byte, _ int) bool {
func isBinary(content []byte) bool {
maybeStr := string(content)
runeCnt := utf8.RuneCount(content)
runeIndex := 0
Expand Down
11 changes: 6 additions & 5 deletions http/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ func previewHandler(imgSvc ImgService, fileCache FileCache, enableThumbnails, re
}

file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: "/" + vars["path"],
Modify: d.user.Perm.Modify,
Expand: true,
Checker: d,
Fs: d.user.Fs,
Path: "/" + vars["path"],
Modify: d.user.Perm.Modify,
Expand: true,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
if err != nil {
return errToStatus(err), err
Expand Down
11 changes: 6 additions & 5 deletions http/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ var withHashFile = func(fn handleFunc) handleFunc {
d.user = user

file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: link.Path,
Modify: d.user.Perm.Modify,
Expand: true,
Checker: d,
Fs: d.user.Fs,
Path: link.Path,
Modify: d.user.Perm.Modify,
Expand: true,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
if err != nil {
return errToStatus(err), err
Expand Down
11 changes: 6 additions & 5 deletions http/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ var rawHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data)
}

file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: false,
Checker: d,
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
if err != nil {
return errToStatus(err), err
Expand Down
22 changes: 12 additions & 10 deletions http/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import (

var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: true,
Checker: d,
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: true,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
if err != nil {
return errToStatus(err), err
Expand Down Expand Up @@ -58,11 +59,12 @@ func resourceDeleteHandler(fileCache FileCache) handleFunc {
}

file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: true,
Checker: d,
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: true,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
if err != nil {
return errToStatus(err), err
Expand Down
23 changes: 12 additions & 11 deletions settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,18 @@ func (s *Settings) GetRules() []rules.Rule {

// Server specific settings.
type Server struct {
Root string `json:"root"`
BaseURL string `json:"baseURL"`
Socket string `json:"socket"`
TLSKey string `json:"tlsKey"`
TLSCert string `json:"tlsCert"`
Port string `json:"port"`
Address string `json:"address"`
Log string `json:"log"`
EnableThumbnails bool `json:"enableThumbnails"`
ResizePreview bool `json:"resizePreview"`
EnableExec bool `json:"enableExec"`
Root string `json:"root"`
BaseURL string `json:"baseURL"`
Socket string `json:"socket"`
TLSKey string `json:"tlsKey"`
TLSCert string `json:"tlsCert"`
Port string `json:"port"`
Address string `json:"address"`
Log string `json:"log"`
EnableThumbnails bool `json:"enableThumbnails"`
ResizePreview bool `json:"resizePreview"`
EnableExec bool `json:"enableExec"`
TypeDetectionByHeader bool `json:"typeDetectionByHeader"`
}

// Clean cleans any variables that might need cleaning.
Expand Down

0 comments on commit 6914063

Please sign in to comment.