From 6e04c97bb9d3e689e583f347588740d2d214e62b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 27 Jun 2017 14:26:12 +0100 Subject: [PATCH] consistency --- assets.go | 6 +++--- checksum.go | 4 ++-- command.go | 6 +++--- download.go | 14 +++++++------- editor.go | 30 +++++++++++++++--------------- filemanager.go | 43 ++++++++++++++++++++++++------------------- http.go | 7 ++++--- http_listing.go | 20 ++++++++++---------- http_put.go | 2 +- search.go | 6 +++--- webdav.go | 20 ++++++++++---------- 11 files changed, 82 insertions(+), 76 deletions(-) diff --git a/assets.go b/assets.go index 81498d59..2b1af10a 100644 --- a/assets.go +++ b/assets.go @@ -12,7 +12,7 @@ import ( const assetsURL = "/_internal" // Serve provides the needed assets for the front-end -func serveAssets(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func serveAssets(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { // gets the filename to be used with Assets function filename := strings.TrimPrefix(r.URL.Path, assetsURL) @@ -22,10 +22,10 @@ func serveAssets(ctx *requestContext, w http.ResponseWriter, r *http.Request) (i switch { case strings.HasPrefix(filename, "/css"): filename = strings.Replace(filename, "/css/", "", 1) - file, err = ctx.FileManager.assets.css.Bytes(filename) + file, err = c.fm.assets.css.Bytes(filename) case strings.HasPrefix(filename, "/js"): filename = strings.Replace(filename, "/js/", "", 1) - file, err = ctx.FileManager.assets.js.Bytes(filename) + file, err = c.fm.assets.js.Bytes(filename) default: err = errors.New("not found") } diff --git a/checksum.go b/checksum.go index db4bfb79..ba7bc865 100644 --- a/checksum.go +++ b/checksum.go @@ -14,10 +14,10 @@ import ( ) // checksum calculates the hash of a file. Supports MD5, SHA1, SHA256 and SHA512. -func checksum(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func checksum(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { query := r.URL.Query().Get("checksum") - file, err := os.Open(ctx.Info.Path) + file, err := os.Open(c.fi.Path) if err != nil { return errorToHTTP(err, true), err } diff --git a/command.go b/command.go index 7e1ccaaa..cf35bdb4 100644 --- a/command.go +++ b/command.go @@ -22,7 +22,7 @@ var ( ) // command handles the requests for VCS related commands: git, svn and mercurial -func command(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func command(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 { @@ -51,7 +51,7 @@ func command(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, // Check if the command is allowed allowed := false - for _, cmd := range ctx.User.Commands { + for _, cmd := range c.us.Commands { if cmd == command[0] { allowed = true } @@ -77,7 +77,7 @@ func command(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, } // Gets the path and initializes a buffer. - path := ctx.User.scope + "/" + r.URL.Path + path := c.us.scope + "/" + r.URL.Path path = filepath.Clean(path) buff := new(bytes.Buffer) diff --git a/download.go b/download.go index 1010553c..6dbdbb0d 100644 --- a/download.go +++ b/download.go @@ -14,12 +14,12 @@ import ( // download creates an archive in one of the supported formats (zip, tar, // tar.gz or tar.bz2) and sends it to be downloaded. -func download(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func download(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { query := r.URL.Query().Get("download") - if !ctx.Info.IsDir { - w.Header().Set("Content-Disposition", "attachment; filename="+ctx.Info.Name) - http.ServeFile(w, r, ctx.Info.Path) + if !c.fi.IsDir { + w.Header().Set("Content-Disposition", "attachment; filename="+c.fi.Name) + http.ServeFile(w, r, c.fi.Path) return 0, nil } @@ -34,11 +34,11 @@ func download(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, return http.StatusInternalServerError, err } - files = append(files, filepath.Join(ctx.Info.Path, name)) + files = append(files, filepath.Join(c.fi.Path, name)) } } else { - files = append(files, ctx.Info.Path) + files = append(files, c.fi.Path) } if query == "true" { @@ -84,7 +84,7 @@ func download(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, return http.StatusInternalServerError, err } - name := ctx.Info.Name + name := c.fi.Name if name == "." || name == "" { name = "download" } diff --git a/editor.go b/editor.go index 3a5e40f4..feb6c0ed 100644 --- a/editor.go +++ b/editor.go @@ -89,22 +89,22 @@ Error: // serveSingle serves a single file in an editor (if it is editable), shows the // plain file, or downloads it if it can't be shown. -func serveSingle(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func serveSingle(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { var err error - if err = ctx.Info.RetrieveFileType(); err != nil { + if err = c.fi.RetrieveFileType(); err != nil { return errorToHTTP(err, true), err } p := &page{ - Name: ctx.Info.Name, - Path: ctx.Info.VirtualPath, + Name: c.fi.Name, + Path: c.fi.VirtualPath, IsDir: false, - Data: ctx.Info, - User: ctx.User, - PrefixURL: ctx.FileManager.prefixURL, - BaseURL: ctx.FileManager.RootURL(), - WebDavURL: ctx.FileManager.WebDavURL(), + Data: c.fi, + User: c.us, + PrefixURL: c.fm.prefixURL, + BaseURL: c.fm.RootURL(), + WebDavURL: c.fm.WebDavURL(), } // If the request accepts JSON, we send the file information. @@ -112,23 +112,23 @@ func serveSingle(ctx *requestContext, w http.ResponseWriter, r *http.Request) (i return p.PrintAsJSON(w) } - if ctx.Info.Type == "text" { - if err = ctx.Info.Read(); err != nil { + if c.fi.Type == "text" { + if err = c.fi.Read(); err != nil { return errorToHTTP(err, true), err } } - if ctx.Info.CanBeEdited() && ctx.User.AllowEdit { - p.Data, err = getEditor(r, ctx.Info) + if c.fi.CanBeEdited() && c.us.AllowEdit { + p.Data, err = getEditor(r, c.fi) p.Editor = true if err != nil { return http.StatusInternalServerError, err } - return p.PrintAsHTML(w, ctx.FileManager.assets.templates, "frontmatter", "editor") + return p.PrintAsHTML(w, c.fm.assets.templates, "frontmatter", "editor") } - return p.PrintAsHTML(w, ctx.FileManager.assets.templates, "single") + return p.PrintAsHTML(w, c.fm.assets.templates, "single") } func editorClass(mode string) string { diff --git a/filemanager.go b/filemanager.go index 4beb9aec..dc6894e9 100644 --- a/filemanager.go +++ b/filemanager.go @@ -232,23 +232,28 @@ func (m *FileManager) NewUser(username string) error { // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { var ( - ctx = &requestContext{ - FileManager: m, - User: nil, - Info: nil, + c = &requestContext{ + fm: m, + us: nil, + fi: nil, } code int err error ) - // Strip the baseURL from the request URL. - r.URL.Path = strings.TrimPrefix(r.URL.Path, m.baseURL) + // Checks if the URL contains the baseURL. If so, it strips it. Otherwise, + // it throws an error. + if p := strings.TrimPrefix(r.URL.Path, m.baseURL); len(p) < len(r.URL.Path) { + r.URL.Path = p + } else { + return http.StatusNotFound, nil + } // Checks if the URL matches the Assets URL. Returns the asset if the // method is GET and Status Forbidden otherwise. if matchURL(r.URL.Path, assetsURL) { if r.Method == http.MethodGet { - return serveAssets(ctx, w, r) + return serveAssets(c, w, r) } return http.StatusForbidden, nil @@ -256,14 +261,14 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er username, _, _ := r.BasicAuth() if _, ok := m.Users[username]; ok { - ctx.User = m.Users[username] + c.us = m.Users[username] } else { - ctx.User = m.User + c.us = m.User } // Checks if the request URL is for the WebDav server. if matchURL(r.URL.Path, m.webDavURL) { - return serveWebDAV(ctx, w, r) + return serveWebDAV(c, w, r) } w.Header().Set("x-frame-options", "SAMEORIGIN") @@ -271,7 +276,7 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er w.Header().Set("x-xss-protection", "1; mode=block") // Checks if the User is allowed to access this file - if !ctx.User.Allowed(r.URL.Path) { + if !c.us.Allowed(r.URL.Path) { if r.Method == http.MethodGet { return htmlError( w, http.StatusForbidden, @@ -283,18 +288,18 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er } if r.URL.Query().Get("search") != "" { - return search(ctx, w, r) + return search(c, w, r) } if r.URL.Query().Get("command") != "" { - return command(ctx, w, r) + return command(c, w, r) } if r.Method == http.MethodGet { var f *fileInfo // Obtains the information of the directory/file. - f, err = getInfo(r.URL, m, ctx.User) + f, err = getInfo(r.URL, m, c.us) if err != nil { if r.Method == http.MethodGet { return htmlError(w, code, err) @@ -304,7 +309,7 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er return code, err } - ctx.Info = f + c.fi = f // If it's a dir and the path doesn't end with a trailing slash, // redirect the user. @@ -315,16 +320,16 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, er switch { case r.URL.Query().Get("download") != "": - code, err = download(ctx, w, r) + code, err = download(c, w, r) case !f.IsDir && r.URL.Query().Get("checksum") != "": - code, err = checksum(ctx, w, r) + code, err = checksum(c, w, r) case r.URL.Query().Get("raw") == "true" && !f.IsDir: http.ServeFile(w, r, f.Path) code, err = 0, nil case f.IsDir: - code, err = serveListing(ctx, w, r) + code, err = serveListing(c, w, r) default: - code, err = serveSingle(ctx, w, r) + code, err = serveSingle(c, w, r) } if err != nil { diff --git a/http.go b/http.go index 3078d692..e42583f1 100644 --- a/http.go +++ b/http.go @@ -6,10 +6,11 @@ import ( "strings" ) +// requestContext contains the needed information to make handlers work. type requestContext struct { - User *User - FileManager *FileManager - Info *fileInfo + us *User + fm *FileManager + fi *fileInfo } // responseWriterNoBody is a wrapper used to suprress the body of the response diff --git a/http_listing.go b/http_listing.go index a46fdee3..ff98eded 100644 --- a/http_listing.go +++ b/http_listing.go @@ -10,22 +10,22 @@ import ( ) // serveListing presents the user with a listage of a directory folder. -func serveListing(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func serveListing(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { var err error // Loads the content of the directory - listing, err := getListing(ctx.User, ctx.Info.VirtualPath, ctx.FileManager.RootURL()+r.URL.Path) + listing, err := getListing(c.us, c.fi.VirtualPath, c.fm.RootURL()+r.URL.Path) if err != nil { return errorToHTTP(err, true), err } listing.Context = httpserver.Context{ - Root: http.Dir(ctx.User.scope), + Root: http.Dir(c.us.scope), Req: r, URL: r.URL, } - cookieScope := ctx.FileManager.RootURL() + cookieScope := c.fm.RootURL() if cookieScope == "" { cookieScope = "/" } @@ -80,17 +80,17 @@ func serveListing(ctx *requestContext, w http.ResponseWriter, r *http.Request) ( p := &page{ minimal: r.Header.Get("Minimal") == "true", Name: listing.Name, - Path: ctx.Info.VirtualPath, + Path: c.fi.VirtualPath, IsDir: true, - User: ctx.User, - PrefixURL: ctx.FileManager.prefixURL, - BaseURL: ctx.FileManager.RootURL(), - WebDavURL: ctx.FileManager.WebDavURL(), + User: c.us, + PrefixURL: c.fm.prefixURL, + BaseURL: c.fm.RootURL(), + WebDavURL: c.fm.WebDavURL(), Display: displayMode, Data: listing, } - return p.PrintAsHTML(w, ctx.FileManager.assets.templates, "listing") + return p.PrintAsHTML(w, c.fm.assets.templates, "listing") } // handleSortOrder gets and stores for a Listing the 'sort' and 'order', diff --git a/http_put.go b/http_put.go index 484700e0..dec63d98 100644 --- a/http_put.go +++ b/http_put.go @@ -14,7 +14,7 @@ import ( ) // put is used to update a file that was edited -func put(ctx *requestContext, w http.ResponseWriter, r *http.Request) (err error) { +func put(c *requestContext, w http.ResponseWriter, r *http.Request) (err error) { var ( data = map[string]interface{}{} file []byte diff --git a/search.go b/search.go index 6f6b8d72..fde33f13 100644 --- a/search.go +++ b/search.go @@ -43,7 +43,7 @@ func parseSearch(value string) *searchOptions { } // search searches for a file or directory. -func search(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +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 { @@ -73,7 +73,7 @@ func search(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, e search = parseSearch(value) scope := strings.TrimPrefix(r.URL.Path, "/") scope = "/" + scope - scope = ctx.User.scope + scope + scope = c.us.scope + scope scope = strings.Replace(scope, "\\", "/", -1) scope = filepath.Clean(scope) @@ -91,7 +91,7 @@ func search(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, e } if strings.Contains(path, term) { - if !ctx.User.Allowed(path) { + if !c.us.Allowed(path) { return nil } diff --git a/webdav.go b/webdav.go index d42a0ee2..031ae9d4 100644 --- a/webdav.go +++ b/webdav.go @@ -8,11 +8,11 @@ import ( ) // serveWebDAV handles the webDAV route of the File Manager. -func serveWebDAV(ctx *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { +func serveWebDAV(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { var err error // Checks for user permissions relatively to this path. - if !ctx.User.Allowed(strings.TrimPrefix(r.URL.Path, ctx.FileManager.webDavURL)) { + if !c.us.Allowed(strings.TrimPrefix(r.URL.Path, c.fm.webDavURL)) { return http.StatusForbidden, nil } @@ -26,8 +26,8 @@ func serveWebDAV(ctx *requestContext, w http.ResponseWriter, r *http.Request) (i // // It was decided on https://github.com/hacdias/caddy-filemanager/issues/85 // that GET, for collections, will return the same as PROPFIND method. - path := strings.Replace(r.URL.Path, ctx.FileManager.webDavURL, "", 1) - path = ctx.User.scope + "/" + path + path := strings.Replace(r.URL.Path, c.fm.webDavURL, "", 1) + path = c.us.scope + "/" + path path = filepath.Clean(path) var i os.FileInfo @@ -45,28 +45,28 @@ func serveWebDAV(ctx *requestContext, w http.ResponseWriter, r *http.Request) (i } } case "PROPPATCH", "MOVE", "PATCH", "PUT", "DELETE": - if !ctx.User.AllowEdit { + if !c.us.AllowEdit { return http.StatusForbidden, nil } case "MKCOL", "COPY": - if !ctx.User.AllowNew { + if !c.us.AllowNew { return http.StatusForbidden, nil } } // Preprocess the PUT request if it's the case if r.Method == http.MethodPut { - if err = ctx.FileManager.BeforeSave(r, ctx.FileManager, ctx.User); err != nil { + if err = c.fm.BeforeSave(r, c.fm, c.us); err != nil { return http.StatusInternalServerError, err } - if put(ctx, w, r) != nil { + if put(c, w, r) != nil { return http.StatusInternalServerError, err } } - ctx.FileManager.handler.ServeHTTP(w, r) - if err = ctx.FileManager.AfterSave(r, ctx.FileManager, ctx.User); err != nil { + c.fm.handler.ServeHTTP(w, r) + if err = c.fm.AfterSave(r, c.fm, c.us); err != nil { return http.StatusInternalServerError, err }