diff --git a/caddyhttp/push/handler.go b/caddyhttp/push/handler.go index a651338e..fcc6ab0b 100644 --- a/caddyhttp/push/handler.go +++ b/caddyhttp/push/handler.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/mholt/caddy/caddyhttp/httpserver" + "github.com/mholt/caddy/caddyhttp/staticfiles" ) func (h Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { @@ -25,7 +26,13 @@ func (h Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, erro // push first outer: for _, rule := range h.Rules { - if httpserver.Path(r.URL.Path).Matches(rule.Path) { + urlPath := r.URL.Path + matches := httpserver.Path(urlPath).Matches(rule.Path) + // Also check IndexPages when requesting a directory + if !matches { + _, matches = httpserver.IndexFile(h.Root, urlPath, staticfiles.IndexPages) + } + if matches { for _, resource := range rule.Resources { pushErr := pusher.Push(resource.Path, &http.PushOptions{ Method: resource.Method, diff --git a/caddyhttp/push/handler_test.go b/caddyhttp/push/handler_test.go index 343ab746..40903b6f 100644 --- a/caddyhttp/push/handler_test.go +++ b/caddyhttp/push/handler_test.go @@ -2,8 +2,11 @@ package push import ( "errors" + "io/ioutil" "net/http" "net/http/httptest" + "os" + "path/filepath" "reflect" "testing" @@ -307,6 +310,63 @@ func TestMiddlewareShouldInterceptLinkHeaderPusherError(t *testing.T) { comparePushedResources(t, expectedPushedResources, pushingWriter.pushed) } +func TestMiddlewareShouldPushIndexFile(t *testing.T) { + // given + indexFile := "/index.html" + request, err := http.NewRequest(http.MethodGet, "/", nil) // Request root directory, not indexfile itself + if err != nil { + t.Fatalf("Could not create HTTP request: %v", err) + } + + root, err := ioutil.TempDir("", "caddy") + if err != nil { + t.Fatalf("Could not create temporary directory: %v", err) + } + defer os.Remove(root) + + middleware := Middleware{ + Next: httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { + return 0, nil + }), + Rules: []Rule{ + {Path: indexFile, Resources: []Resource{ + {Path: "/index.css", Method: http.MethodGet}, + }}, + }, + Root: http.Dir(root), + } + + indexFilePath := filepath.Join(root, indexFile) + _, err = os.Create(indexFilePath) + if err != nil { + t.Fatalf("Could not create index file: %s: %v", indexFile, err) + } + defer os.Remove(indexFilePath) + + pushingWriter := &MockedPusher{ + ResponseWriter: httptest.NewRecorder(), + returnedError: errors.New("Cannot push right now"), + } + + // when + _, err2 := middleware.ServeHTTP(pushingWriter, request) + + // then + if err2 != nil { + t.Error("Should not return error") + } + + expectedPushedResources := map[string]*http.PushOptions{ + "/index.css": { + Method: http.MethodGet, + Header: http.Header{}, + }, + } + + comparePushedResources(t, expectedPushedResources, pushingWriter.pushed) + +} + func comparePushedResources(t *testing.T, expected, actual map[string]*http.PushOptions) { if len(expected) != len(actual) { t.Errorf("Expected %d pushed resources, actual: %d", len(expected), len(actual)) diff --git a/caddyhttp/push/push.go b/caddyhttp/push/push.go index b2063bd7..2c5821a5 100644 --- a/caddyhttp/push/push.go +++ b/caddyhttp/push/push.go @@ -24,6 +24,7 @@ type ( Middleware struct { Next httpserver.Handler Rules []Rule + Root http.FileSystem } ruleOp func([]Resource) diff --git a/caddyhttp/push/setup.go b/caddyhttp/push/setup.go index b6c33176..28e8dbc5 100644 --- a/caddyhttp/push/setup.go +++ b/caddyhttp/push/setup.go @@ -34,8 +34,9 @@ func setup(c *caddy.Controller) error { return err } - httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { - return Middleware{Next: next, Rules: rules} + cfg := httpserver.GetConfig(c) + cfg.AddMiddleware(func(next httpserver.Handler) httpserver.Handler { + return Middleware{Next: next, Rules: rules, Root: http.Dir(cfg.Root)} }) return nil