Return 0 when there is no error (Golang)
Former-commit-id: e7c4248761e085dd763c7d2fb93e3b364d46cc1f [formerly 59e9b4ed8b656dc61119e7c758fb47ee30c36ad6] [formerly 4e5e9413d14ec8ee0a3a2abbee7f607b15910315 [formerly b214fdd0eb]]
Former-commit-id: 1dc992ecd0b0169e66f854083554ae825ffa3ddf [formerly 65f85346c9875abcaaa0fa97fa8689ebea774f37]
Former-commit-id: aac3de2cf26430814b9db7073b42f5791ff2a566
			
			
				pull/726/head
			
			
		
							parent
							
								
									0f7c341086
								
							
						
					
					
						commit
						c3c6c8f3d6
					
				
							
								
								
									
										18
									
								
								checksum.go
								
								
								
								
							
							
						
						
									
										18
									
								
								checksum.go
								
								
								
								
							|  | @ -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 |  | ||||||
| } |  | ||||||
|  | @ -91,5 +91,5 @@ func serveDownload(c *requestContext, w http.ResponseWriter, r *http.Request) (i | ||||||
| 
 | 
 | ||||||
| 	w.Header().Set("Content-Disposition", "attachment; filename="+name+extension) | 	w.Header().Set("Content-Disposition", "attachment; filename="+name+extension) | ||||||
| 	io.Copy(w, file) | 	io.Copy(w, file) | ||||||
| 	return http.StatusOK, nil | 	return 0, nil | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								editor.go
								
								
								
								
							
							
						
						
									
										10
									
								
								editor.go
								
								
								
								
							|  | @ -13,14 +13,14 @@ import ( | ||||||
| 
 | 
 | ||||||
| // editor contains the information to fill the editor template.
 | // editor contains the information to fill the editor template.
 | ||||||
| type editor struct { | type editor struct { | ||||||
| 	Class       string | 	Class       string `json:"class"` | ||||||
| 	Mode        string | 	Mode        string `json:"mode"` | ||||||
| 	Visual      bool | 	Visual      bool   `json:"visual"` | ||||||
| 	Content     string | 	Content     string `json:"content"` | ||||||
| 	FrontMatter struct { | 	FrontMatter struct { | ||||||
| 		Content *frontmatter.Content | 		Content *frontmatter.Content | ||||||
| 		Rune    rune | 		Rune    rune | ||||||
| 	} | 	} `json:"frontmatter"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getEditor gets the editor based on a Info struct
 | // getEditor gets the editor based on a Info struct
 | ||||||
|  |  | ||||||
							
								
								
									
										82
									
								
								http.go
								
								
								
								
							
							
						
						
									
										82
									
								
								http.go
								
								
								
								
							|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -125,6 +126,87 @@ func serveHTTP(c *requestContext, w http.ResponseWriter, r *http.Request) (int, | ||||||
| 	return http.StatusNotImplemented, nil | 	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
 | // responseWriterNoBody is a wrapper used to suprress the body of the response
 | ||||||
| // to a request. Mainly used for HEAD requests.
 | // to a request. Mainly used for HEAD requests.
 | ||||||
| type responseWriterNoBody struct { | type responseWriterNoBody struct { | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								page.go
								
								
								
								
							
							
						
						
									
										39
									
								
								page.go
								
								
								
								
							|  | @ -2,21 +2,16 @@ package filemanager | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"encoding/base64" |  | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"html/template" | 	"html/template" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 |  | ||||||
| 	rice "github.com/GeertJohan/go.rice" |  | ||||||
| 	"github.com/hacdias/filemanager/variables" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // functions contains the non-standard functions that are available
 | // functions contains the non-standard functions that are available
 | ||||||
| // to use on the HTML templates.
 | // to use on the HTML templates.
 | ||||||
| var functions = template.FuncMap{ | var functions = template.FuncMap{ | ||||||
| 	"Defined": variables.FieldInStruct, |  | ||||||
| 	"CSS": func(s string) template.CSS { | 	"CSS": func(s string) template.CSS { | ||||||
| 		return template.CSS(s) | 		return template.CSS(s) | ||||||
| 	}, | 	}, | ||||||
|  | @ -24,9 +19,6 @@ var functions = template.FuncMap{ | ||||||
| 		a, _ := json.Marshal(v) | 		a, _ := json.Marshal(v) | ||||||
| 		return template.JS(a) | 		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.
 | // page contains the information needed to fill a page template.
 | ||||||
|  | @ -100,12 +92,25 @@ func (p page) PreviousLink() string { | ||||||
| 	return path | 	return path | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // PrintHTML formats the page in HTML and executes the template
 | func (p page) Render(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { | ||||||
| func (p page) PrintHTML(w http.ResponseWriter, box *rice.Box) (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 | 	var tpl *template.Template | ||||||
| 
 | 
 | ||||||
| 	// Get the template from the assets
 | 	// 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
 | 	// Check if there is some error. If so, the template doesn't exist
 | ||||||
| 	if err != nil { | 	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") | 	w.Header().Set("Content-Type", "text/html; charset=utf-8") | ||||||
| 	_, err = buf.WriteTo(w) | 	_, 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 { | 	if err != nil { | ||||||
| 		return http.StatusInternalServerError, err | 		return http.StatusInternalServerError, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	w.Header().Set("Content-Type", "application/json; charset=utf-8") | 	return 0, nil | ||||||
| 	if _, err := w.Write(marsh); err != nil { |  | ||||||
| 		return http.StatusInternalServerError, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return http.StatusOK, nil |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // htmlError prints the error page
 | // htmlError prints the error page
 | ||||||
|  |  | ||||||
|  | @ -112,5 +112,5 @@ func search(c *requestContext, w http.ResponseWriter, r *http.Request) (int, err | ||||||
| 		return http.StatusInternalServerError, err | 		return http.StatusInternalServerError, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return http.StatusOK, nil | 	return 0, nil | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								serve.go
								
								
								
								
							
							
						
						
									
										16
									
								
								serve.go
								
								
								
								
							|  | @ -3,7 +3,6 @@ package filemanager | ||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func serveDefault(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) { | 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.
 | 	return c.pg.Render(c, w, r) | ||||||
| 	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) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // serveListing presents the user with a listage of a directory folder.
 | // 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) | 	listing.Display = displayMode(w, r, cookieScope) | ||||||
| 	c.pg.Data = listing | 	c.pg.Data = listing | ||||||
| 
 | 
 | ||||||
| 	// If it's a JSON request, print only the items... in JSON! (such a surprise -_-)
 | 	return c.pg.Render(c, w, r) | ||||||
| 	if strings.Contains(r.Header.Get("Accept"), "application/json") { |  | ||||||
| 		return c.pg.PrintJSON(w) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return c.pg.PrintHTML(w, c.fm.templates) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // displayMode obtaisn the display mode from URL, or from the
 | // displayMode obtaisn the display mode from URL, or from the
 | ||||||
|  |  | ||||||
							
								
								
									
										74
									
								
								webdav.go
								
								
								
								
							
							
						
						
									
										74
									
								
								webdav.go
								
								
								
								
							|  | @ -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 |  | ||||||
| } |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Henrique Dias
						Henrique Dias