mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-26 21:53:48 +03:00
caddyhttp: Add plaintext response to file_server browse
(#6093)
* Added plaintext support to file_server browser This commit is twofold: First it adds a new optional field, `return_type`, to `browser` for setting the default format of the returned index (html, json or plaintext). This is used when the `Accept` header is set to `/*`. Second, it adds a preliminary `text/plain` support to the `file_server` browser that returns a text representation of the file system, when an `Accept: text/plain` header is present, with the behavior discussed above. * Added more details and better formatting to plaintext browser * Replaced returnType conditions with a switch statement * Simplify --------- Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
1217449609
commit
45132c5b24
2 changed files with 40 additions and 8 deletions
|
@ -28,6 +28,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"text/tabwriter"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -111,13 +112,42 @@ func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w ht
|
||||||
|
|
||||||
acceptHeader := strings.ToLower(strings.Join(r.Header["Accept"], ","))
|
acceptHeader := strings.ToLower(strings.Join(r.Header["Accept"], ","))
|
||||||
|
|
||||||
// write response as either JSON or HTML
|
switch {
|
||||||
if strings.Contains(acceptHeader, "application/json") {
|
case strings.Contains(acceptHeader, "application/json"):
|
||||||
if err := json.NewEncoder(buf).Encode(listing.Items); err != nil {
|
if err := json.NewEncoder(buf).Encode(listing.Items); err != nil {
|
||||||
return caddyhttp.Error(http.StatusInternalServerError, err)
|
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
} else {
|
|
||||||
|
case strings.Contains(acceptHeader, "text/plain"):
|
||||||
|
writer := tabwriter.NewWriter(buf, 0, 8, 1, '\t', tabwriter.AlignRight)
|
||||||
|
|
||||||
|
// Header on top
|
||||||
|
if _, err := fmt.Fprintln(writer, "Name\tSize\tModified"); err != nil {
|
||||||
|
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lines to separate the header
|
||||||
|
if _, err := fmt.Fprintln(writer, "----\t----\t--------"); err != nil {
|
||||||
|
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual files
|
||||||
|
for _, item := range listing.Items {
|
||||||
|
if _, err := fmt.Fprintf(writer, "%s\t%s\t%s\n",
|
||||||
|
item.Name, item.HumanSize(), item.HumanModTime("January 2, 2006 at 15:04:05"),
|
||||||
|
); err != nil {
|
||||||
|
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writer.Flush(); err != nil {
|
||||||
|
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
|
||||||
|
default:
|
||||||
var fs http.FileSystem
|
var fs http.FileSystem
|
||||||
if fsrv.Root != "" {
|
if fsrv.Root != "" {
|
||||||
fs = http.Dir(repl.ReplaceAll(fsrv.Root, "."))
|
fs = http.Dir(repl.ReplaceAll(fsrv.Root, "."))
|
||||||
|
|
|
@ -113,13 +113,15 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
fsrv.Browse = new(Browse)
|
fsrv.Browse = new(Browse)
|
||||||
d.Args(&fsrv.Browse.TemplateFile)
|
d.Args(&fsrv.Browse.TemplateFile)
|
||||||
for nesting := d.Nesting(); d.NextBlock(nesting); {
|
for nesting := d.Nesting(); d.NextBlock(nesting); {
|
||||||
if d.Val() != "reveal_symlinks" {
|
switch d.Val() {
|
||||||
|
case "reveal_symlinks":
|
||||||
|
if fsrv.Browse.RevealSymlinks {
|
||||||
|
return d.Err("Symlinks path reveal is already enabled")
|
||||||
|
}
|
||||||
|
fsrv.Browse.RevealSymlinks = true
|
||||||
|
default:
|
||||||
return d.Errf("unknown subdirective '%s'", d.Val())
|
return d.Errf("unknown subdirective '%s'", d.Val())
|
||||||
}
|
}
|
||||||
if fsrv.Browse.RevealSymlinks {
|
|
||||||
return d.Err("Symlinks path reveal is already enabled")
|
|
||||||
}
|
|
||||||
fsrv.Browse.RevealSymlinks = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "precompressed":
|
case "precompressed":
|
||||||
|
|
Loading…
Reference in a new issue