diff --git a/caddy/filemanager/README_NEW.md b/caddy/filemanager/README_NEW.md new file mode 100644 index 00000000..40f1b9c2 --- /dev/null +++ b/caddy/filemanager/README_NEW.md @@ -0,0 +1,53 @@ +# filemanager - a caddy plugin + +filemanager provides WebDAV features and a file managing interface within the specified directory and it can be used to upload, delete, preview, rename and edit your files within that directory. It is an implementation of [hacdias/filemanager](https://github.com/hacdias/filemanager) library. + +Note that if you are handling large files you might run into troubles due to the defaults of [`timeouts`](https://caddyserver.com/docs/timeouts) plugin. Check its [documentation](https://caddyserver.com/docs/timeouts) to learn more about that plugin. + +For information about the working of filemanager itself, go to the [main repository](https://github.com/hacdias/filemanager). + +## Get Started + +To start using this plugin you just need to go to the [download Caddy page](https://caddyserver.com/download) and choose `filemanager` in the directives section. For further information on how Caddy works refer to [its documentation](https://caddyserver.com/docs). + +## Syntax + +``` +filemanager [baseurl] [scope] { + database path +} +``` + +All of the options above are optional. + ++ **baseurl** is the URL where you will access the File Manager interface. Defaults to `/`. ++ **scope** is the path, relative or absolute, to the directory you want to browse in. Defaults to `./`. ++ **path** is the database path where File Manager will store the settings that aren't included in the Caddyfile. By default, the database will be stored on `.caddy` folder and its name will be an hashed combination of the host and the `baseurl`. It is **highly** recommended to set this option. Otherwise, whenever you change the host or the baseurl, your settings will be lost or you will need to point to the previous database. + +## Examples + +Show the directory where Caddy is being executed at the root of the domain: + +``` +filemanager +``` + + +Show the content of `foo` at the root of the domain: + +``` +filemanager / ./foo +``` + +Show the directory where Caddy is being executed at `/filemanager`: + +``` +filemanager /filemanager +``` + +Show the content of `foo` at `/bar`: + +``` +filemanager /bar /show +} +``` diff --git a/caddy/filemanager/filemanager.go b/caddy/filemanager/filemanager.go index 81e6d597..e14b179f 100644 --- a/caddy/filemanager/filemanager.go +++ b/caddy/filemanager/filemanager.go @@ -4,10 +4,10 @@ package filemanager import ( - "log" + "crypto/sha256" + "encoding/hex" "net/http" "os" - "os/exec" "path/filepath" "strings" @@ -69,13 +69,9 @@ func parse(c *caddy.Controller) ([]*config, error) { ) for c.Next() { - // TODO: - // filemanager [baseurl] [baseScope] { - // database path - // } - baseURL := "/" baseScope := "." + database := "" // Get the baseURL and baseScope args := c.RemainingArgs() @@ -88,7 +84,38 @@ func parse(c *caddy.Controller) ([]*config, error) { baseScope = args[1] } - fm, err := New("./this.db", User{ + for c.NextBlock() { + switch c.Val() { + case "database": + if !c.NextArg() { + return nil, c.ArgErr() + } + + database = c.Val() + } + } + + caddyConf := httpserver.GetConfig(c) + + // If there is no database path on the settings, + // store one in .caddy/filemanager/name.db. + if database == "" { + path := filepath.Join(caddy.AssetsPath(), "filemanager") + err := os.MkdirAll(path, 0700) + if err != nil { + return nil, err + } + + // The name of the database is the hashed value of a string composed + // by the host, address path and the baseurl of this File Manager + // instance. + hasher := sha256.New() + hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + baseURL)) + sha := hex.EncodeToString(hasher.Sum(nil)) + database = filepath.Join(path, sha+".db") + } + + fm, err := New(database, User{ Username: "admin", Password: "admin", AllowCommands: true, @@ -108,8 +135,6 @@ func parse(c *caddy.Controller) ([]*config, error) { return nil, err } - caddyConf := httpserver.GetConfig(c) - m := &config{FileManager: fm} m.SetBaseURL(baseURL) m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/")) @@ -120,49 +145,3 @@ func parse(c *caddy.Controller) ([]*config, error) { return configs, nil } - -func makeCommand(c *caddy.Controller, m *config) (Command, error) { - fn := func(r *http.Request, c *FileManager, u *User) error { return nil } - - args := c.RemainingArgs() - if len(args) == 0 { - return fn, c.ArgErr() - } - - nonblock := false - if len(args) > 1 && args[len(args)-1] == "&" { - // Run command in background; non-blocking - nonblock = true - args = args[:len(args)-1] - } - - command, args, err := caddy.SplitCommandAndArgs(strings.Join(args, " ")) - if err != nil { - return fn, c.Err(err.Error()) - } - - fn = func(r *http.Request, c *FileManager, u *User) error { - path := strings.Replace(r.URL.Path, m.baseURL+"/files", "", 1) - path = string(u.FileSystem) + "/" + path - path = filepath.Clean(path) - - for i := range args { - args[i] = strings.Replace(args[i], "{path}", path, -1) - } - - cmd := exec.Command(command, args...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - if nonblock { - log.Printf("[INFO] Nonblocking Command:\"%s %s\"", command, strings.Join(args, " ")) - return cmd.Start() - } - - log.Printf("[INFO] Blocking Command:\"%s %s\"", command, strings.Join(args, " ")) - return cmd.Run() - } - - return fn, nil -}