package browse
import (
"fmt"
"io/ioutil"
"net/http"
"text/template"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
func init() {
caddy.RegisterPlugin(caddy.Plugin{
Name: "browse",
ServerType: "http",
Action: setup,
})
}
// setup configures a new Browse middleware instance.
func setup(c *caddy.Controller) error {
configs, err := browseParse(c)
if err != nil {
return err
}
b := Browse{
Configs: configs,
IgnoreIndexes: false,
}
httpserver.GetConfig(c.Key).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
b.Next = next
return b
})
return nil
}
func browseParse(c *caddy.Controller) ([]Config, error) {
var configs []Config
cfg := httpserver.GetConfig(c.Key)
appendCfg := func(bc Config) error {
for _, c := range configs {
if c.PathScope == bc.PathScope {
return fmt.Errorf("duplicate browsing config for %s", c.PathScope)
}
}
configs = append(configs, bc)
return nil
}
for c.Next() {
var bc Config
// First argument is directory to allow browsing; default is site root
if c.NextArg() {
bc.PathScope = c.Val()
} else {
bc.PathScope = "/"
}
bc.Root = http.Dir(cfg.Root)
theRoot, err := bc.Root.Open("/") // catch a missing path early
if err != nil {
return configs, err
}
defer theRoot.Close()
_, err = theRoot.Readdir(-1)
if err != nil {
return configs, err
}
// Second argument would be the template file to use
var tplText string
if c.NextArg() {
tplBytes, err := ioutil.ReadFile(c.Val())
if err != nil {
return configs, err
}
tplText = string(tplBytes)
} else {
tplText = defaultTemplate
}
// Build the template
tpl, err := template.New("listing").Parse(tplText)
if err != nil {
return configs, err
}
bc.Template = tpl
// Save configuration
err = appendCfg(bc)
if err != nil {
return configs, err
}
}
return configs, nil
}
// The default template to use when serving up directory listings
const defaultTemplate = `
{{.Name}}
{{range $url, $name := .BreadcrumbMap}}{{$name}}{{if ne $url "/"}}/{{end}}{{end}}
{{.NumDirs}} director{{if eq 1 .NumDirs}}y{{else}}ies{{end}}{{.NumFiles}} file{{if ne 1 .NumFiles}}s{{end}}
{{- if ne 0 .ItemsLimitedTo}}
(of which only {{.ItemsLimitedTo}} are displayed)
{{- end}}
{{- if and (eq .Sort "name") (ne .Order "desc")}}
Name
{{- else if and (eq .Sort "name") (ne .Order "asc")}}
Name
{{- else}}
Name
{{- end}}
{{- if and (eq .Sort "size") (ne .Order "desc")}}
Size
{{- else if and (eq .Sort "size") (ne .Order "asc")}}
Size
{{- else}}
Size
{{- end}}
{{- if and (eq .Sort "time") (ne .Order "desc")}}
Modified
{{- else if and (eq .Sort "time") (ne .Order "asc")}}
Modified
{{- else}}
Modified
{{- end}}