diff options
Diffstat (limited to 'modules/caddyhttp/staticfiles/browse.go')
-rw-r--r-- | modules/caddyhttp/staticfiles/browse.go | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/modules/caddyhttp/staticfiles/browse.go b/modules/caddyhttp/staticfiles/browse.go deleted file mode 100644 index 2bb130f..0000000 --- a/modules/caddyhttp/staticfiles/browse.go +++ /dev/null @@ -1,157 +0,0 @@ -package staticfiles - -import ( - "bytes" - "encoding/json" - "html/template" - "net/http" - "os" - "path" - "strings" - - "bitbucket.org/lightcodelabs/caddy2" - "bitbucket.org/lightcodelabs/caddy2/modules/caddyhttp" -) - -// Browse configures directory browsing. -type Browse struct { - TemplateFile string `json:"template_file"` - - template *template.Template -} - -func (sf *StaticFiles) serveBrowse(dirPath string, w http.ResponseWriter, r *http.Request) error { - dir, err := sf.openFile(dirPath, w) - if err != nil { - return err - } - defer dir.Close() - - repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer) - - listing, err := sf.loadDirectoryContents(dir, r.URL.Path, repl) - switch { - case os.IsPermission(err): - return caddyhttp.Error(http.StatusForbidden, err) - case os.IsNotExist(err): - return caddyhttp.Error(http.StatusNotFound, err) - case err != nil: - return caddyhttp.Error(http.StatusInternalServerError, err) - } - - sf.browseApplyQueryParams(w, r, &listing) - - // write response as either JSON or HTML - var buf *bytes.Buffer - acceptHeader := strings.ToLower(strings.Join(r.Header["Accept"], ",")) - if strings.Contains(acceptHeader, "application/json") { - if buf, err = sf.browseWriteJSON(listing); err != nil { - return caddyhttp.Error(http.StatusInternalServerError, err) - } - w.Header().Set("Content-Type", "application/json; charset=utf-8") - } else { - if buf, err = sf.browseWriteHTML(listing); err != nil { - return caddyhttp.Error(http.StatusInternalServerError, err) - } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - } - buf.WriteTo(w) - - return nil - - // TODO: Sigh... do we have to put this here? - // // Browsing navigation gets messed up if browsing a directory - // // that doesn't end in "/" (which it should, anyway) - // u := *r.URL - // if u.Path == "" { - // u.Path = "/" - // } - // if u.Path[len(u.Path)-1] != '/' { - // u.Path += "/" - // http.Redirect(w, r, u.String(), http.StatusMovedPermanently) - // return http.StatusMovedPermanently, nil - // } - - // return b.ServeListing(w, r, requestedFilepath, bc) -} - -func (sf *StaticFiles) loadDirectoryContents(dir *os.File, urlPath string, repl caddy2.Replacer) (browseListing, error) { - files, err := dir.Readdir(-1) - if err != nil { - return browseListing{}, err - } - - // determine if user can browse up another folder - curPathDir := path.Dir(strings.TrimSuffix(urlPath, "/")) - canGoUp := strings.HasPrefix(curPathDir, sf.Root) - - return sf.directoryListing(files, canGoUp, urlPath, repl), nil -} - -// browseApplyQueryParams applies query parameters to the listing. -// It mutates the listing and may set cookies. -func (sf *StaticFiles) browseApplyQueryParams(w http.ResponseWriter, r *http.Request, listing *browseListing) { - sortParam := r.URL.Query().Get("sort") - orderParam := r.URL.Query().Get("order") - limitParam := r.URL.Query().Get("limit") - - // first figure out what to sort by - switch sortParam { - case "": - sortParam = sortByNameDirFirst - if sortCookie, sortErr := r.Cookie("sort"); sortErr == nil { - sortParam = sortCookie.Value - } - case sortByName, sortByNameDirFirst, sortBySize, sortByTime: - http.SetCookie(w, &http.Cookie{Name: "sort", Value: sortParam, Secure: r.TLS != nil}) - } - - // then figure out the order - switch orderParam { - case "": - orderParam = "asc" - if orderCookie, orderErr := r.Cookie("order"); orderErr == nil { - orderParam = orderCookie.Value - } - case "asc", "desc": - http.SetCookie(w, &http.Cookie{Name: "order", Value: orderParam, Secure: r.TLS != nil}) - } - - // finally, apply the sorting and limiting - listing.applySortAndLimit(sortParam, orderParam, limitParam) -} - -func (sf *StaticFiles) browseWriteJSON(listing browseListing) (*bytes.Buffer, error) { - buf := new(bytes.Buffer) - err := json.NewEncoder(buf).Encode(listing.Items) - return buf, err -} - -func (sf *StaticFiles) browseWriteHTML(listing browseListing) (*bytes.Buffer, error) { - buf := new(bytes.Buffer) - err := sf.Browse.template.Execute(buf, listing) - return buf, err -} - -// isSymlink return true if f is a symbolic link -func isSymlink(f os.FileInfo) bool { - return f.Mode()&os.ModeSymlink != 0 -} - -// isSymlinkTargetDir return true if f's symbolic link target -// is a directory. Return false if not a symbolic link. -// TODO: Re-implement -func isSymlinkTargetDir(f os.FileInfo, urlPath string) bool { - // if !isSymlink(f) { - // return false - // } - - // // TODO: Ensure path is sanitized - // target:= path.Join(root, urlPath, f.Name())) - // targetInfo, err := os.Stat(target) - // if err != nil { - // return false - // } - // return targetInfo.IsDir() - return false -} |