From 82929b122ab1a2e98d17f403b0da26158c8aea72 Mon Sep 17 00:00:00 2001 From: Matthew Holt <mholt@users.noreply.github.com> Date: Mon, 23 Jan 2017 22:06:29 -0700 Subject: [PATCH] Ensure active Caddyfile, if in site, is hidden no matter the cwd --- caddyhttp/browse/browse.go | 9 +++++---- caddyhttp/httpserver/plugin.go | 32 +++++++++++++++++++++++++----- caddyhttp/httpserver/siteconfig.go | 3 +++ caddyhttp/root/root.go | 4 ++++ caddyhttp/root/root_test.go | 5 ++++- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/caddyhttp/browse/browse.go b/caddyhttp/browse/browse.go index ce5b58af0..36064c1d7 100644 --- a/caddyhttp/browse/browse.go +++ b/caddyhttp/browse/browse.go @@ -245,16 +245,17 @@ func directoryListing(files []os.FileInfo, canGoUp bool, urlPath string, config // 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) { - var bc *Config // See if there's a browse configuration to match the path + var bc *Config for i := range b.Configs { if httpserver.Path(r.URL.Path).Matches(b.Configs[i].PathScope) { bc = &b.Configs[i] - goto inScope + break } } - return b.Next.ServeHTTP(w, r) -inScope: + if bc == nil { + return b.Next.ServeHTTP(w, r) + } // Browse works on existing directories; delegate everything else requestedFilepath, err := bc.Fs.Root.Open(r.URL.Path) diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index b1fcb9773..d9ad8ab89 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -7,6 +7,7 @@ import ( "net" "net/url" "os" + "path/filepath" "strings" "time" @@ -21,7 +22,7 @@ func init() { flag.StringVar(&Host, "host", DefaultHost, "Default host") flag.StringVar(&Port, "port", DefaultPort, "Default port") flag.StringVar(&Root, "root", DefaultRoot, "Root path of default site") - flag.DurationVar(&GracefulTimeout, "grace", 5*time.Second, "Maximum duration of graceful shutdown") // TODO + flag.DurationVar(&GracefulTimeout, "grace", 5*time.Second, "Maximum duration of graceful shutdown") flag.BoolVar(&HTTP2, "http2", true, "Use HTTP/2") flag.BoolVar(&QUIC, "quic", false, "Use experimental QUIC") @@ -44,10 +45,31 @@ func init() { NewContext: newContext, }) caddy.RegisterCaddyfileLoader("short", caddy.LoaderFunc(shortCaddyfileLoader)) + caddy.RegisterParsingCallback(serverType, "root", hideCaddyfile) caddy.RegisterParsingCallback(serverType, "tls", activateHTTPS) caddytls.RegisterConfigGetter(serverType, func(c *caddy.Controller) *caddytls.Config { return GetConfig(c).TLS }) } +// hideCaddyfile hides the source/origin Caddyfile if it is within the +// site root. This function should be run after parsing the root directive. +func hideCaddyfile(cctx caddy.Context) error { + ctx := cctx.(*httpContext) + for _, cfg := range ctx.siteConfigs { + absRoot, err := filepath.Abs(cfg.Root) + if err != nil { + return err + } + absOriginCaddyfile, err := filepath.Abs(cfg.originCaddyfile) + if err != nil { + return err + } + if strings.HasPrefix(absOriginCaddyfile, absRoot) { + cfg.HiddenFiles = append(cfg.HiddenFiles, strings.TrimPrefix(absOriginCaddyfile, absRoot)) + } + } + return nil +} + func newContext() caddy.Context { return &httpContext{keysToSiteConfigs: make(map[string]*SiteConfig)} } @@ -95,10 +117,10 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd // Save the config to our master list, and key it for lookups cfg := &SiteConfig{ - Addr: addr, - Root: Root, - TLS: &caddytls.Config{Hostname: addr.Host}, - HiddenFiles: []string{sourceFile}, + Addr: addr, + Root: Root, + TLS: &caddytls.Config{Hostname: addr.Host}, + originCaddyfile: sourceFile, } h.saveConfig(key, cfg) } diff --git a/caddyhttp/httpserver/siteconfig.go b/caddyhttp/httpserver/siteconfig.go index 2980d3770..e5e18b50b 100644 --- a/caddyhttp/httpserver/siteconfig.go +++ b/caddyhttp/httpserver/siteconfig.go @@ -33,6 +33,9 @@ type SiteConfig struct { // Max amount of bytes a request can send on a given path MaxRequestBodySizes []PathLimit + + // The path to the Caddyfile used to generate this site config + originCaddyfile string } // PathLimit is a mapping from a site's path to its corresponding diff --git a/caddyhttp/root/root.go b/caddyhttp/root/root.go index 50ada1103..b3dded1c6 100644 --- a/caddyhttp/root/root.go +++ b/caddyhttp/root/root.go @@ -23,6 +23,10 @@ func setupRoot(c *caddy.Controller) error { return c.ArgErr() } config.Root = c.Val() + if c.NextArg() { + // only one argument allowed + return c.ArgErr() + } } // Check if root path exists diff --git a/caddyhttp/root/root_test.go b/caddyhttp/root/root_test.go index 471d9a24a..daeb9eea0 100644 --- a/caddyhttp/root/root_test.go +++ b/caddyhttp/root/root_test.go @@ -52,6 +52,9 @@ func TestRoot(t *testing.T) { { `root `, true, "", parseErrContent, }, + { + `root /a /b`, true, "", parseErrContent, + }, { fmt.Sprintf(`root %s`, inaccessiblePath), true, "", unableToAccessErrContent, }, @@ -68,7 +71,7 @@ func TestRoot(t *testing.T) { cfg := httpserver.GetConfig(c) if test.shouldErr && err == nil { - t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input) + t.Errorf("Test %d: Expected error but got nil for input '%s'", i, test.input) } if err != nil {