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, c *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, c.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
 | 
						|
}
 |