From 132f2a9cc330fd626b01c87e9ca510a31f416d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=96stanb=C3=A4ck?= Date: Thu, 1 Jun 2017 14:18:07 +0200 Subject: [PATCH] browse: Show symbolic links and target's type properly (#1667) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Browse: Show symbolic links and targets type properly * gofmt Signed-off-by: Jonas Östanbäck * Move symbolic link check in to isSymlinkTargetDir Signed-off-by: Jonas Östanbäck * Revert template change and show sym link folders as normal folders * browse: Updated icons including symlink indicators --- caddyhttp/browse/browse.go | 48 +++++++++++++++++------ caddyhttp/browse/setup.go | 79 +++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 48 deletions(-) diff --git a/caddyhttp/browse/browse.go b/caddyhttp/browse/browse.go index 8694d2de..97687665 100644 --- a/caddyhttp/browse/browse.go +++ b/caddyhttp/browse/browse.go @@ -112,12 +112,13 @@ func (l Listing) Breadcrumbs() []Crumb { // FileInfo is the info about a particular file or directory type FileInfo struct { - Name string - Size int64 - URL string - ModTime time.Time - Mode os.FileMode - IsDir bool + Name string + Size int64 + URL string + ModTime time.Time + Mode os.FileMode + IsDir bool + IsSymlink bool } // HumanSize returns the size of the file as a human-readable string @@ -258,12 +259,13 @@ func directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, config url := url.URL{Path: "./" + name} // prepend with "./" to fix paths with ':' in the name fileinfos = append(fileinfos, FileInfo{ - IsDir: f.IsDir(), - Name: f.Name(), - Size: f.Size(), - URL: url.String(), - ModTime: f.ModTime().UTC(), - Mode: f.Mode(), + IsDir: f.IsDir() || isSymlinkTargetDir(f), + IsSymlink: isSymlink(f), + Name: f.Name(), + Size: f.Size(), + URL: url.String(), + ModTime: f.ModTime().UTC(), + Mode: f.Mode(), }) } @@ -277,6 +279,28 @@ func directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, config }, hasIndexFile } +// 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. +func isSymlinkTargetDir(f os.FileInfo) bool { + if !isSymlink(f) { + return false + } + target, err := os.Readlink(f.Name()) + if err != nil { + return false + } + targetInfo, err := os.Lstat(target) + if err != nil { + return false + } + return targetInfo.IsDir() +} + // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. // If so, control is handed over to ServeListing. func (b Browse) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { diff --git a/caddyhttp/browse/setup.go b/caddyhttp/browse/setup.go index 64a54c23..0abf728e 100644 --- a/caddyhttp/browse/setup.go +++ b/caddyhttp/browse/setup.go @@ -150,16 +150,22 @@ h1 { white-space: nowrap; overflow-x: hidden; text-overflow: ellipsis; + color: #999; } h1 a { - color: inherit; + color: #000; + margin: 0 4px; } h1 a:hover { text-decoration: underline; } +h1 a:first-child { + margin: 0; +} + main { display: block; } @@ -284,6 +290,18 @@ footer { padding-right: 5%; text-align: right; } + + h1 { + color: #000; + } + + h1 a { + margin: 0; + } + + #filter { + max-width: 100px; + } } @@ -291,45 +309,32 @@ footer { - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + @@ -419,9 +424,9 @@ footer { {{- if .IsDir}} - + {{- else}} - + {{- end}} {{html .Name}} @@ -443,6 +448,8 @@ footer {