From b214fdd0ebe2bb564cbe64a12dbac725bc4d3f66 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 28 Jun 2017 19:06:08 +0100 Subject: [PATCH] Return 0 when there is no error (Golang) --- checksum.go | 18 ------------ download.go | 2 +- editor.go | 10 +++---- http.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ page.go | 39 +++++++++++-------------- search.go | 2 +- serve.go | 16 ++--------- webdav.go | 74 ----------------------------------------------- 8 files changed, 108 insertions(+), 135 deletions(-) delete mode 100644 checksum.go delete mode 100644 webdav.go diff --git a/checksum.go b/checksum.go deleted file mode 100644 index b8d35226..00000000 --- a/checksum.go +++ /dev/null @@ -1,18 +0,0 @@ -package filemanager - -import "net/http" - -// serveChecksum calculates the hash of a file. Supports MD5, SHA1, SHA256 and SHA512. -func serveChecksum(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { - query := r.URL.Query().Get("checksum") - - val, err := c.fi.Checksum(query) - if err == errInvalidOption { - return http.StatusBadRequest, err - } else if err != nil { - return http.StatusInternalServerError, err - } - - w.Write([]byte(val)) - return http.StatusOK, nil -} diff --git a/download.go b/download.go index 6834a44c..4c7618b3 100644 --- a/download.go +++ b/download.go @@ -91,5 +91,5 @@ func serveDownload(c *requestContext, w http.ResponseWriter, r *http.Request) (i w.Header().Set("Content-Disposition", "attachment; filename="+name+extension) io.Copy(w, file) - return http.StatusOK, nil + return 0, nil } diff --git a/editor.go b/editor.go index 3ffcf872..a0efa5a3 100644 --- a/editor.go +++ b/editor.go @@ -13,14 +13,14 @@ import ( // editor contains the information to fill the editor template. type editor struct { - Class string - Mode string - Visual bool - Content string + Class string `json:"class"` + Mode string `json:"mode"` + Visual bool `json:"visual"` + Content string `json:"content"` FrontMatter struct { Content *frontmatter.Content Rune rune - } + } `json:"frontmatter"` } // getEditor gets the editor based on a Info struct diff --git a/http.go b/http.go index 98b9392a..c6c135a2 100644 --- a/http.go +++ b/http.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "os" + "path/filepath" "strings" ) @@ -125,6 +126,87 @@ func serveHTTP(c *requestContext, w http.ResponseWriter, r *http.Request) (int, return http.StatusNotImplemented, nil } +// serveWebDAV handles the webDAV route of the File Manager. +func serveWebDAV(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { + var err error + + // Checks for user permissions relatively to this path. + if !c.us.Allowed(strings.TrimPrefix(r.URL.Path, c.fm.webDavURL)) { + return http.StatusForbidden, nil + } + + switch r.Method { + case "GET", "HEAD": + // Excerpt from RFC4918, section 9.4: + // + // GET, when applied to a collection, may return the contents of an + // "index.html" resource, a human-readable view of the contents of + // the collection, or something else altogether. + // + // 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, c.fm.webDavURL, "", 1) + path = c.us.scope + "/" + path + path = filepath.Clean(path) + + var i os.FileInfo + i, err = os.Stat(path) + if err != nil { + // Is there any error? WebDav will handle it... no worries. + break + } + + if i.IsDir() { + r.Method = "PROPFIND" + + if r.Method == "HEAD" { + w = newResponseWriterNoBody(w) + } + } + case "PROPPATCH", "MOVE", "PATCH", "PUT", "DELETE": + if !c.us.AllowEdit { + return http.StatusForbidden, nil + } + case "MKCOL", "COPY": + if !c.us.AllowNew { + return http.StatusForbidden, nil + } + } + + // Preprocess the PUT request if it's the case + if r.Method == http.MethodPut { + if err = c.fm.BeforeSave(r, c.fm, c.us); err != nil { + return http.StatusInternalServerError, err + } + + if put(c, w, r) != nil { + return http.StatusInternalServerError, err + } + } + + c.fm.handler.ServeHTTP(w, r) + if err = c.fm.AfterSave(r, c.fm, c.us); err != nil { + return http.StatusInternalServerError, err + } + + return 0, nil +} + +// serveChecksum calculates the hash of a file. Supports MD5, SHA1, SHA256 and SHA512. +func serveChecksum(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { + query := r.URL.Query().Get("checksum") + + val, err := c.fi.Checksum(query) + if err == errInvalidOption { + return http.StatusBadRequest, err + } else if err != nil { + return http.StatusInternalServerError, err + } + + w.Write([]byte(val)) + return 0, nil +} + // responseWriterNoBody is a wrapper used to suprress the body of the response // to a request. Mainly used for HEAD requests. type responseWriterNoBody struct { diff --git a/page.go b/page.go index 24251d3e..3adf8f3d 100644 --- a/page.go +++ b/page.go @@ -2,21 +2,16 @@ package filemanager import ( "bytes" - "encoding/base64" "encoding/json" "html/template" "net/http" "strconv" "strings" - - rice "github.com/GeertJohan/go.rice" - "github.com/hacdias/filemanager/variables" ) // functions contains the non-standard functions that are available // to use on the HTML templates. var functions = template.FuncMap{ - "Defined": variables.FieldInStruct, "CSS": func(s string) template.CSS { return template.CSS(s) }, @@ -24,9 +19,6 @@ var functions = template.FuncMap{ a, _ := json.Marshal(v) return template.JS(a) }, - "EncodeBase64": func(s string) string { - return base64.StdEncoding.EncodeToString([]byte(s)) - }, } // page contains the information needed to fill a page template. @@ -100,12 +92,25 @@ func (p page) PreviousLink() string { return path } -// PrintHTML formats the page in HTML and executes the template -func (p page) PrintHTML(w http.ResponseWriter, box *rice.Box) (int, error) { +func (p page) Render(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { + if strings.Contains(r.Header.Get("Accept"), "application/json") { + marsh, err := json.MarshalIndent(p, "", " ") + if err != nil { + return http.StatusInternalServerError, err + } + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + if _, err := w.Write(marsh); err != nil { + return http.StatusInternalServerError, err + } + + return 0, nil + } + var tpl *template.Template // Get the template from the assets - file, err := box.String("index.html") + file, err := c.fm.templates.String("index.html") // Check if there is some error. If so, the template doesn't exist if err != nil { @@ -125,22 +130,12 @@ func (p page) PrintHTML(w http.ResponseWriter, box *rice.Box) (int, error) { w.Header().Set("Content-Type", "text/html; charset=utf-8") _, err = buf.WriteTo(w) - return http.StatusOK, err -} -// PrintAsJSON prints the current Page information in JSON -func (p page) PrintJSON(w http.ResponseWriter) (int, error) { - marsh, err := json.MarshalIndent(p, "", " ") if err != nil { return http.StatusInternalServerError, err } - w.Header().Set("Content-Type", "application/json; charset=utf-8") - if _, err := w.Write(marsh); err != nil { - return http.StatusInternalServerError, err - } - - return http.StatusOK, nil + return 0, nil } // htmlError prints the error page diff --git a/search.go b/search.go index 5581ce4d..bee1c8c5 100644 --- a/search.go +++ b/search.go @@ -112,5 +112,5 @@ func search(c *requestContext, w http.ResponseWriter, r *http.Request) (int, err return http.StatusInternalServerError, err } - return http.StatusOK, nil + return 0, nil } diff --git a/serve.go b/serve.go index 93adf300..0c9515d1 100644 --- a/serve.go +++ b/serve.go @@ -3,7 +3,6 @@ package filemanager import ( "net/http" "strconv" - "strings" ) func serveDefault(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { @@ -53,13 +52,7 @@ func serveDefault(c *requestContext, w http.ResponseWriter, r *http.Request) (in } } - // If the request accepts JSON, we send the file information. - if strings.Contains(r.Header.Get("Accept"), "application/json") { - c.pg.Data = c.fi - return c.pg.PrintJSON(w) - } - - return c.pg.PrintHTML(w, c.fm.templates) + return c.pg.Render(c, w, r) } // serveListing presents the user with a listage of a directory folder. @@ -98,12 +91,7 @@ func serveListing(c *requestContext, w http.ResponseWriter, r *http.Request) (in listing.Display = displayMode(w, r, cookieScope) c.pg.Data = listing - // If it's a JSON request, print only the items... in JSON! (such a surprise -_-) - if strings.Contains(r.Header.Get("Accept"), "application/json") { - return c.pg.PrintJSON(w) - } - - return c.pg.PrintHTML(w, c.fm.templates) + return c.pg.Render(c, w, r) } // displayMode obtaisn the display mode from URL, or from the diff --git a/webdav.go b/webdav.go deleted file mode 100644 index 031ae9d4..00000000 --- a/webdav.go +++ /dev/null @@ -1,74 +0,0 @@ -package filemanager - -import ( - "net/http" - "os" - "path/filepath" - "strings" -) - -// serveWebDAV handles the webDAV route of the File Manager. -func serveWebDAV(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { - var err error - - // Checks for user permissions relatively to this path. - if !c.us.Allowed(strings.TrimPrefix(r.URL.Path, c.fm.webDavURL)) { - return http.StatusForbidden, nil - } - - switch r.Method { - case "GET", "HEAD": - // Excerpt from RFC4918, section 9.4: - // - // GET, when applied to a collection, may return the contents of an - // "index.html" resource, a human-readable view of the contents of - // the collection, or something else altogether. - // - // 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, c.fm.webDavURL, "", 1) - path = c.us.scope + "/" + path - path = filepath.Clean(path) - - var i os.FileInfo - i, err = os.Stat(path) - if err != nil { - // Is there any error? WebDav will handle it... no worries. - break - } - - if i.IsDir() { - r.Method = "PROPFIND" - - if r.Method == "HEAD" { - w = newResponseWriterNoBody(w) - } - } - case "PROPPATCH", "MOVE", "PATCH", "PUT", "DELETE": - if !c.us.AllowEdit { - return http.StatusForbidden, nil - } - case "MKCOL", "COPY": - if !c.us.AllowNew { - return http.StatusForbidden, nil - } - } - - // Preprocess the PUT request if it's the case - if r.Method == http.MethodPut { - if err = c.fm.BeforeSave(r, c.fm, c.us); err != nil { - return http.StatusInternalServerError, err - } - - if put(c, w, r) != nil { - return http.StatusInternalServerError, err - } - } - - c.fm.handler.ServeHTTP(w, r) - if err = c.fm.AfterSave(r, c.fm, c.us); err != nil { - return http.StatusInternalServerError, err - } - - return 0, nil -}