Put search and command in the same file

Former-commit-id: ec4d0fe64d8ecd06411c54d269c7a046448ba8b0 [formerly 4d08a0093ba6fe20a8c377596a43674751b455be] [formerly aa20a96198a064a352448e01ecb828a71fb2691f [formerly 2d82967b44]]
Former-commit-id: 8e64e961f6132daf323cb7a5c62f421cdfa8d94e [formerly 9367098494f6bc0c38bb7e27ed11a06cfc47982a]
Former-commit-id: 6625f650cf28818b3b7cdec029c9eb4add3da228
pull/726/head
Henrique Dias 2017-07-25 12:05:26 +01:00
parent d962ac060a
commit 3acc23cc18
2 changed files with 107 additions and 116 deletions

116
search.go
View File

@ -1,116 +0,0 @@
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(c *RequestContext, w http.ResponseWriter, r *http.Request) (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.TrimPrefix(r.URL.Path, "/")
scope = "/" + scope
scope = string(c.User.FileSystem) + 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.TrimPrefix(path, scope)
path = strings.TrimPrefix(path, "/")
path = strings.Replace(path, "\\", "/", -1)
is := false
for _, term := range search.Terms {
if is {
break
}
if strings.Contains(path, term) {
if !c.User.Allowed(path) {
return nil
}
is = true
}
}
if !is {
return nil
}
return conn.WriteMessage(websocket.TextMessage, []byte(path))
})
if err != nil {
return http.StatusInternalServerError, err
}
return 0, nil
}

View File

@ -3,6 +3,7 @@ package filemanager
import ( import (
"bytes" "bytes"
"net/http" "net/http"
"os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
@ -133,3 +134,109 @@ func command(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, er
return 0, nil return 0, nil
} }
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(c *RequestContext, w http.ResponseWriter, r *http.Request) (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.TrimPrefix(r.URL.Path, "/")
scope = "/" + scope
scope = string(c.User.FileSystem) + 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.TrimPrefix(path, scope)
path = strings.TrimPrefix(path, "/")
path = strings.Replace(path, "\\", "/", -1)
is := false
for _, term := range search.Terms {
if is {
break
}
if strings.Contains(path, term) {
if !c.User.Allowed(path) {
return nil
}
is = true
}
}
if !is {
return nil
}
return conn.WriteMessage(websocket.TextMessage, []byte(path))
})
if err != nil {
return http.StatusInternalServerError, err
}
return 0, nil
}