From 20f76a256e35ee4bcf9c6ed75693680ddfe58a72 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Thu, 6 Jul 2017 09:24:01 +0200 Subject: [PATCH] Push resources for indexFiles when surfing to directories Use httpserver.IndexFile() to determine index files Test if middleware pushes indexfile when requesting directory Fix codereview issues Serve original request first, push later Revert "Serve original request first, push later" This reverts commit 2c66f01115747e5665ba7f2d33e2fd551dc31877. --- caddyhttp/push/handler.go | 9 ++++- caddyhttp/push/handler_test.go | 60 ++++++++++++++++++++++++++++++++++ caddyhttp/push/push.go | 1 + caddyhttp/push/setup.go | 5 +-- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/caddyhttp/push/handler.go b/caddyhttp/push/handler.go index a651338e0..fcc6ab0b0 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 343ab7460..40903b6fa 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 b2063bd72..2c5821a5b 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 b6c331764..28e8dbc53 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