diff --git a/editor.go b/editor.go index 4e785c88..c42deee1 100644 --- a/editor.go +++ b/editor.go @@ -24,7 +24,7 @@ type editor struct { } // newEditor gets the editor based on a FileInfo struct -func newEditor(r *http.Request, i *file) (*editor, error) { +func newEditor(r *http.Request, i *fileInfo) (*editor, error) { var err error // Create a new editor variable and set the mode diff --git a/file.go b/file.go index 70961ce2..5e0599b9 100644 --- a/file.go +++ b/file.go @@ -13,8 +13,8 @@ import ( humanize "github.com/dustin/go-humanize" ) -// file contains the information about a particular file or directory. -type file struct { +// fileInfo contains the information about a particular file or directory. +type fileInfo struct { Name string Size int64 URL string @@ -30,11 +30,11 @@ type file struct { UserAllowed bool // Indicates if the user has enough permissions } -// getFile retrieves the file information and the error, if there is any. -func getFile(url *url.URL, c *Config, u *User) (*file, error) { +// getFileInfo retrieves the file information and the error, if there is any. +func getFileInfo(url *url.URL, c *FileManager, u *User) (*fileInfo, error) { var err error - i := &file{URL: c.PrefixURL + url.Path} + i := &fileInfo{URL: c.PrefixURL + url.Path} i.VirtualPath = strings.Replace(url.Path, c.BaseURL, "", 1) i.VirtualPath = strings.TrimPrefix(i.VirtualPath, "/") i.VirtualPath = "/" + i.VirtualPath @@ -75,7 +75,7 @@ var textExtensions = [...]string{ // RetrieveFileType obtains the mimetype and a simplified internal Type // using the first 512 bytes from the file. -func (i *file) RetrieveFileType() error { +func (i fileInfo) RetrieveFileType() error { i.Mimetype = mime.TypeByExtension(i.Extension) if i.Mimetype == "" { @@ -126,7 +126,7 @@ func (i *file) RetrieveFileType() error { } // Reads the file. -func (i *file) Read() error { +func (i fileInfo) Read() error { if len(i.Content) != 0 { return nil } @@ -140,22 +140,22 @@ func (i *file) Read() error { } // StringifyContent returns the string version of Raw -func (i file) StringifyContent() string { +func (i fileInfo) StringifyContent() string { return string(i.Content) } // HumanSize returns the size of the file as a human-readable string // in IEC format (i.e. power of 2 or base 1024). -func (i file) HumanSize() string { +func (i fileInfo) HumanSize() string { return humanize.IBytes(uint64(i.Size)) } // HumanModTime returns the modified time of the file as a human-readable string. -func (i file) HumanModTime(format string) string { +func (i fileInfo) HumanModTime(format string) string { return i.ModTime.Format(format) } // CanBeEdited checks if the extension of a file is supported by the editor -func (i file) CanBeEdited() bool { +func (i fileInfo) CanBeEdited() bool { return i.Type == "text" } diff --git a/filemanager.go b/filemanager.go index 6ad2cb29..6fc6107c 100644 --- a/filemanager.go +++ b/filemanager.go @@ -10,8 +10,8 @@ import ( "golang.org/x/net/webdav" ) -// Config is a configuration for browsing in a particular path. -type Config struct { +// FileManager is a configuration for browsing in a particular path. +type FileManager struct { *User PrefixURL string // A part of the URL that is stripped from the http.Request BaseURL string // The base URL of FileManager interface @@ -27,8 +27,8 @@ type Config struct { // New creates a new FileManager object with the default settings // for a certain scope. -func New(scope string) *Config { - cfg := &Config{ +func New(scope string) *FileManager { + fm := &FileManager{ User: &User{ Scope: scope, FileSystem: webdav.Dir(scope), @@ -46,26 +46,26 @@ func New(scope string) *Config { BaseURL: "", PrefixURL: "", WebDavURL: "/webdav", - BeforeSave: func(r *http.Request, c *Config, u *User) error { return nil }, - AfterSave: func(r *http.Request, c *Config, u *User) error { return nil }, + BeforeSave: func(r *http.Request, c *FileManager, u *User) error { return nil }, + AfterSave: func(r *http.Request, c *FileManager, u *User) error { return nil }, } - cfg.Handler = &webdav.Handler{ - Prefix: cfg.WebDavURL, - FileSystem: cfg.FileSystem, + fm.Handler = &webdav.Handler{ + Prefix: fm.WebDavURL, + FileSystem: fm.FileSystem, LockSystem: webdav.NewMemLS(), } - return cfg + return fm } // AbsoluteURL ... -func (c Config) AbsoluteURL() string { +func (c FileManager) AbsoluteURL() string { return c.PrefixURL + c.BaseURL } // AbsoluteWebdavURL ... -func (c Config) AbsoluteWebdavURL() string { +func (c FileManager) AbsoluteWebdavURL() string { return c.PrefixURL + c.WebDavURL } @@ -113,4 +113,4 @@ func (u User) Allowed(url string) bool { } // Command is a user-defined command that is executed in some moments. -type Command func(r *http.Request, c *Config, u *User) error +type Command func(r *http.Request, c *FileManager, u *User) error diff --git a/http.go b/http.go index 6e49a3f1..d6c851a1 100644 --- a/http.go +++ b/http.go @@ -11,9 +11,9 @@ import ( ) // ServeHTTP starts FileManager. -func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { +func (c *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { var ( - fi *file + fi *fileInfo user *User code int err error @@ -127,7 +127,7 @@ func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) if r.Method == http.MethodGet { // Gets the information of the directory/file - fi, err = getFile(r.URL, c, user) + fi, err = getFileInfo(r.URL, c, user) code = errorToHTTPCode(err, false) if err != nil { if r.Method == http.MethodGet { diff --git a/http_checksum.go b/http_checksum.go index 12039a6a..58f9fe0e 100644 --- a/http_checksum.go +++ b/http_checksum.go @@ -14,7 +14,7 @@ import ( ) // checksum calculates the hash of a filemanager. Supports MD5, SHA1, SHA256 and SHA512. -func (c *Config) checksum(w http.ResponseWriter, r *http.Request, i *file) (int, error) { +func (c *FileManager) checksum(w http.ResponseWriter, r *http.Request, i *fileInfo) (int, error) { query := r.URL.Query().Get("checksum") file, err := os.Open(i.Path) diff --git a/http_command.go b/http_command.go index 2529b152..3893473b 100644 --- a/http_command.go +++ b/http_command.go @@ -22,7 +22,7 @@ var ( ) // command handles the requests for VCS related commands: git, svn and mercurial -func (c *Config) command(w http.ResponseWriter, r *http.Request, u *User) (int, error) { +func (c *FileManager) command(w http.ResponseWriter, r *http.Request, u *User) (int, error) { // Upgrades the connection to a websocket and checks for errors. conn, err := upgrader.Upgrade(w, r, nil) if err != nil { diff --git a/http_download.go b/http_download.go index 6d987d58..f1556153 100644 --- a/http_download.go +++ b/http_download.go @@ -14,7 +14,7 @@ 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 (c *Config) download(w http.ResponseWriter, r *http.Request, i *file) (int, error) { +func (c *FileManager) download(w http.ResponseWriter, r *http.Request, i *fileInfo) (int, error) { query := r.URL.Query().Get("download") if !i.IsDir { diff --git a/http_listing.go b/http_listing.go index 3f82bc7e..11480a88 100644 --- a/http_listing.go +++ b/http_listing.go @@ -10,11 +10,11 @@ import ( ) // serveListing presents the user with a listage of a directory folder. -func (c *Config) serveListing(w http.ResponseWriter, r *http.Request, u *User, i *file) (int, error) { +func (c *FileManager) serveListing(w http.ResponseWriter, r *http.Request, u *User, i *fileInfo) (int, error) { var err error // Loads the content of the directory - listing, err := GetListing(u, i.VirtualPath, c.PrefixURL+r.URL.Path) + listing, err := getListing(u, i.VirtualPath, c.PrefixURL+r.URL.Path) if err != nil { return errorToHTTPCode(err, true), err } diff --git a/http_put.go b/http_put.go index 679b9802..fa41658e 100644 --- a/http_put.go +++ b/http_put.go @@ -14,7 +14,7 @@ import ( ) // preProccessPUT is used to update a file that was edited -func (c *Config) preProccessPUT(w http.ResponseWriter, r *http.Request, u *User) (err error) { +func (c *FileManager) preProccessPUT(w http.ResponseWriter, r *http.Request, u *User) (err error) { var ( data = map[string]interface{}{} file []byte diff --git a/http_search.go b/http_search.go index 8604fcc5..9e656de2 100644 --- a/http_search.go +++ b/http_search.go @@ -43,7 +43,7 @@ func parseSearch(value string) *searchOptions { } // search ... -func (c *Config) search(w http.ResponseWriter, r *http.Request, u *User) (int, error) { +func (c *FileManager) search(w http.ResponseWriter, r *http.Request, u *User) (int, error) { // Upgrades the connection to a websocket and checks for errors. conn, err := upgrader.Upgrade(w, r, nil) if err != nil { diff --git a/http_single.go b/http_single.go index fbf0f47d..32f9dbed 100644 --- a/http_single.go +++ b/http_single.go @@ -7,7 +7,7 @@ import ( // 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 (c *Config) serveSingle(w http.ResponseWriter, r *http.Request, u *User, i *file) (int, error) { +func (c *FileManager) serveSingle(w http.ResponseWriter, r *http.Request, u *User, i *fileInfo) (int, error) { var err error if err = i.RetrieveFileType(); err != nil { diff --git a/http_utils.go b/http_utils.go deleted file mode 100644 index 6ce6f8ea..00000000 --- a/http_utils.go +++ /dev/null @@ -1,24 +0,0 @@ -package filemanager - -import ( - "net/http" - "os" -) - -// errorToHTTPCode converts errors to HTTP Status Code. -func errorToHTTPCode(err error, gone bool) int { - switch { - case os.IsPermission(err): - return http.StatusForbidden - case os.IsNotExist(err): - if !gone { - return http.StatusNotFound - } - - return http.StatusGone - case os.IsExist(err): - return http.StatusGone - default: - return http.StatusInternalServerError - } -} diff --git a/listing.go b/listing.go index 79c53c11..0b4468c9 100644 --- a/listing.go +++ b/listing.go @@ -11,14 +11,14 @@ import ( "github.com/mholt/caddy/caddyhttp/httpserver" ) -// A Listing is the context used to fill out a template. -type Listing struct { +// A listing is the context used to fill out a template. +type listing struct { // The name of the directory (the last element of the path) Name string // The full path of the request relatively to a File System Path string // The items (files and folders) in the path - Items []file + Items []fileInfo // The number of directories in the listing NumDirs int // The number of files (items that aren't directories) in the listing @@ -32,8 +32,8 @@ type Listing struct { httpserver.Context `json:"-"` } -// GetListing gets the information about a specific directory and its files. -func GetListing(u *User, filePath string, baseURL string) (*Listing, error) { +// getListing gets the information about a specific directory and its files. +func getListing(u *User, filePath string, baseURL string) (*listing, error) { // Gets the directory information using the Virtual File System of // the user configuration. file, err := u.FileSystem.OpenFile(context.TODO(), filePath, os.O_RDONLY, 0) @@ -49,7 +49,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) { } var ( - fileinfos []*file + fileinfos []fileInfo dirCount, fileCount int ) @@ -71,7 +71,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) { // Absolute URL url := url.URL{Path: baseURL + name} - i := &file{ + i := fileInfo{ Name: f.Name(), Size: f.Size(), ModTime: f.ModTime(), @@ -85,7 +85,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) { fileinfos = append(fileinfos, i) } - return &Listing{ + return &listing{ Name: path.Base(filePath), Path: filePath, Items: fileinfos, @@ -95,7 +95,7 @@ func GetListing(u *User, filePath string, baseURL string) (*Listing, error) { } // ApplySort applies the sort order using .Order and .Sort -func (l Listing) ApplySort() { +func (l listing) ApplySort() { // Check '.Order' to know how to sort if l.Order == "desc" { switch l.Sort { @@ -124,10 +124,10 @@ func (l Listing) ApplySort() { } } -// Implement sorting for Listing -type byName Listing -type bySize Listing -type byTime Listing +// Implement sorting for listing +type byName listing +type bySize listing +type byTime listing // By Name func (l byName) Len() int { diff --git a/page.go b/page.go index ba46b4f8..0e44acd6 100644 --- a/page.go +++ b/page.go @@ -11,6 +11,15 @@ import ( "strings" ) +// Create the functions map, then the template, check for erros and +// execute the template if there aren't errors +var functionMap = template.FuncMap{ + "Defined": defined, + "CSS": css, + "Marshal": marshal, + "EncodeBase64": encodeBase64, +} + // page contains the informations and functions needed to show the Page type page struct { Info *pageInfo @@ -23,7 +32,7 @@ type pageInfo struct { Path string IsDir bool User *User - Config *Config + Config *FileManager Data interface{} Editor bool Display string diff --git a/functions.go b/utils.go similarity index 67% rename from functions.go rename to utils.go index a85d3991..bb8592ce 100644 --- a/functions.go +++ b/utils.go @@ -5,18 +5,11 @@ import ( "encoding/json" "html/template" "log" + "net/http" + "os" "reflect" ) -// Create the functions map, then the template, check for erros and -// execute the template if there aren't errors -var functionMap = template.FuncMap{ - "Defined": defined, - "CSS": css, - "Marshal": marshal, - "EncodeBase64": encodeBase64, -} - // defined checks if variable is defined in a struct func defined(data interface{}, field string) bool { t := reflect.Indirect(reflect.ValueOf(data)).Type() @@ -45,3 +38,21 @@ func marshal(v interface{}) template.JS { func encodeBase64(s string) string { return base64.StdEncoding.EncodeToString([]byte(s)) } + +// errorToHTTPCode converts errors to HTTP Status Code. +func errorToHTTPCode(err error, gone bool) int { + switch { + case os.IsPermission(err): + return http.StatusForbidden + case os.IsNotExist(err): + if !gone { + return http.StatusNotFound + } + + return http.StatusGone + case os.IsExist(err): + return http.StatusGone + default: + return http.StatusInternalServerError + } +} diff --git a/functions_test.go b/utils_test.go similarity index 100% rename from functions_test.go rename to utils_test.go