mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
9d8928362d
Former-commit-id: 1d455e1df0045f8d3fa7b87245d08464eba20273 [formerly 385ca7846c8085ac4848330e7c2903653945df5e] [formerly 7cb84d0a3e3614c8de24a5a1a96811c2bee40f88 [formerly 2df4efc369
]]
Former-commit-id: 16afb44d65ffd7885d104b340ca5c8c8997b8b36 [formerly b394abd63c8ab34539dc9e68dbd8f12b4795c7b6]
Former-commit-id: a50ef3c36267359ce6b4e52d9c9f3642e616e376
118 lines
2.4 KiB
Go
118 lines
2.4 KiB
Go
package filemanager
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type searchOptions struct {
|
|
CaseInsensitive bool
|
|
Terms []string
|
|
}
|
|
|
|
func parseSearch(value string) *searchOptions {
|
|
opts := &searchOptions{
|
|
CaseInsensitive: strings.Contains(value, "case:insensitive"),
|
|
}
|
|
|
|
// removes the options from the value
|
|
value = strings.Replace(value, "case:insensitive", "", -1)
|
|
value = strings.Replace(value, "case:sensitive", "", -1)
|
|
value = strings.TrimSpace(value)
|
|
|
|
if opts.CaseInsensitive {
|
|
value = strings.ToLower(value)
|
|
}
|
|
|
|
// if the value starts with " and finishes what that character, we will
|
|
// only search for that term
|
|
if value[0] == '"' && value[len(value)-1] == '"' {
|
|
unique := strings.TrimPrefix(value, "\"")
|
|
unique = strings.TrimSuffix(unique, "\"")
|
|
|
|
opts.Terms = []string{unique}
|
|
return opts
|
|
}
|
|
|
|
opts.Terms = strings.Split(value, " ")
|
|
return opts
|
|
}
|
|
|
|
// search searches for a file or directory.
|
|
func search(w http.ResponseWriter, r *http.Request, m *FileManager, u *User) (int, error) {
|
|
// Upgrades the connection to a websocket and checks for errors.
|
|
conn, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer conn.Close()
|
|
|
|
var (
|
|
value string
|
|
search *searchOptions
|
|
message []byte
|
|
)
|
|
|
|
// Starts an infinite loop until a valid command is captured.
|
|
for {
|
|
_, message, err = conn.ReadMessage()
|
|
if err != nil {
|
|
return http.StatusInternalServerError, err
|
|
}
|
|
|
|
if len(message) != 0 {
|
|
value = string(message)
|
|
break
|
|
}
|
|
}
|
|
|
|
search = parseSearch(value)
|
|
scope := strings.Replace(r.URL.Path, m.BaseURL, "", 1)
|
|
scope = strings.TrimPrefix(scope, "/")
|
|
scope = "/" + scope
|
|
scope = u.scope + scope
|
|
scope = strings.Replace(scope, "\\", "/", -1)
|
|
scope = filepath.Clean(scope)
|
|
|
|
err = filepath.Walk(scope, func(path string, f os.FileInfo, err error) error {
|
|
if search.CaseInsensitive {
|
|
path = strings.ToLower(path)
|
|
}
|
|
|
|
path = strings.Replace(path, "\\", "/", -1)
|
|
is := false
|
|
|
|
for _, term := range search.Terms {
|
|
if is {
|
|
break
|
|
}
|
|
|
|
if strings.Contains(path, term) {
|
|
if !u.Allowed(path) {
|
|
return nil
|
|
}
|
|
|
|
is = true
|
|
}
|
|
}
|
|
|
|
if !is {
|
|
return nil
|
|
}
|
|
|
|
path = strings.TrimPrefix(path, scope)
|
|
path = strings.TrimPrefix(path, "/")
|
|
return conn.WriteMessage(websocket.TextMessage, []byte(path))
|
|
})
|
|
|
|
if err != nil {
|
|
return http.StatusInternalServerError, err
|
|
}
|
|
|
|
return http.StatusOK, nil
|
|
}
|