Commit 20f76a25 authored by Thomas De Keulenaer's avatar Thomas De Keulenaer

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.
parent 40b52fb0
......@@ -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,
......
......@@ -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))
......
......@@ -24,6 +24,7 @@ type (
Middleware struct {
Next httpserver.Handler
Rules []Rule
Root http.FileSystem
}
ruleOp func([]Resource)
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment