Skip to content

Commit

Permalink
Add VersionedAssets middleware (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
markuswustenberg authored Sep 9, 2024
1 parent 3b5add7 commit 5c23ef2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
17 changes: 17 additions & 0 deletions httph.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"html/template"
"net/http"
"regexp"
"strings"

"github.com/mitchellh/mapstructure"
Expand Down Expand Up @@ -221,3 +222,19 @@ func GoGet(opts GoGetOptions) Middleware {
})
}
}

// versionedAssetMatcher matches versioned assets like "app.abc123.js".
// See https://regex101.com/r/bGfflm/latest
var versionedAssetMatcher = regexp.MustCompile(`^(?P<name>[^.]+)\.[a-z0-9]+(?P<extension>\.[a-z0-9]+)$`)

// VersionedAssets is Middleware to help serve versioned assets without the version.
// It basically strips the version from the asset path and forwards the request, probably to a static file handler.
func VersionedAssets(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if versionedAssetMatcher.MatchString(r.URL.Path) {
r.URL.Path = versionedAssetMatcher.ReplaceAllString(r.URL.Path, `$1$2`)
}

next.ServeHTTP(w, r)
})
}
24 changes: 24 additions & 0 deletions httph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,27 @@ func TestGoGet(t *testing.T) {
is.True(t, !called)
})
}

func TestVersionedAssets(t *testing.T) {
t.Run("removes version from asset path", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/script.123456.js", nil)
res := httptest.NewRecorder()

h := httph.VersionedAssets(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
h.ServeHTTP(res, req)

is.Equal(t, http.StatusOK, res.Result().StatusCode)
is.Equal(t, "/script.js", req.URL.Path)
})

t.Run("does not modify path without version", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/script.js", nil)
res := httptest.NewRecorder()

h := httph.VersionedAssets(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
h.ServeHTTP(res, req)

is.Equal(t, http.StatusOK, res.Result().StatusCode)
is.Equal(t, "/script.js", req.URL.Path)
})
}

0 comments on commit 5c23ef2

Please sign in to comment.