diff options
Diffstat (limited to 'resources/resource_transformers/integrity')
-rw-r--r-- | resources/resource_transformers/integrity/integrity.go | 25 | ||||
-rw-r--r-- | resources/resource_transformers/integrity/integrity_test.go | 24 |
2 files changed, 41 insertions, 8 deletions
diff --git a/resources/resource_transformers/integrity/integrity.go b/resources/resource_transformers/integrity/integrity.go index 95065603d..1b74de7eb 100644 --- a/resources/resource_transformers/integrity/integrity.go +++ b/resources/resource_transformers/integrity/integrity.go @@ -23,6 +23,8 @@ import ( "html/template" "io" + "github.com/gohugoio/hugo/resources/internal" + "github.com/pkg/errors" "github.com/gohugoio/hugo/resources" @@ -46,8 +48,8 @@ type fingerprintTransformation struct { algo string } -func (t *fingerprintTransformation) Key() resources.ResourceTransformationKey { - return resources.NewResourceTransformationKey("fingerprint", t.algo) +func (t *fingerprintTransformation) Key() internal.ResourceTransformationKey { + return internal.NewResourceTransformationKey("fingerprint", t.algo) } // Transform creates a MD5 hash of the Resource content and inserts that hash before @@ -59,7 +61,17 @@ func (t *fingerprintTransformation) Transform(ctx *resources.ResourceTransformat return err } - io.Copy(io.MultiWriter(h, ctx.To), ctx.From) + var w io.Writer + if rc, ok := ctx.From.(io.ReadSeeker); ok { + // This transformation does not change the content, so try to + // avoid writing to To if we can. + defer rc.Seek(0, 0) + w = h + } else { + w = io.MultiWriter(h, ctx.To) + } + + io.Copy(w, ctx.From) d, err := digest(h) if err != nil { return err @@ -91,15 +103,12 @@ func newHash(algo string) (hash.Hash, error) { // the base64-encoded Subresource Integrity hash, so you will have to stay away from // md5 if you plan to use both. // See https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity -func (c *Client) Fingerprint(res resource.Resource, algo string) (resource.Resource, error) { +func (c *Client) Fingerprint(res resources.ResourceTransformer, algo string) (resource.Resource, error) { if algo == "" { algo = defaultHashAlgo } - return c.rs.Transform( - res, - &fingerprintTransformation{algo: algo}, - ) + return res.Transform(&fingerprintTransformation{algo: algo}) } func integrity(algo string, sum []byte) template.HTMLAttr { diff --git a/resources/resource_transformers/integrity/integrity_test.go b/resources/resource_transformers/integrity/integrity_test.go index cb1caa006..3759e6313 100644 --- a/resources/resource_transformers/integrity/integrity_test.go +++ b/resources/resource_transformers/integrity/integrity_test.go @@ -14,9 +14,13 @@ package integrity import ( + "html/template" "testing" + "github.com/gohugoio/hugo/resources/resource" + qt "github.com/frankban/quicktest" + "github.com/gohugoio/hugo/resources/resource_transformers/htesting" ) func TestHashFromAlgo(t *testing.T) { @@ -46,3 +50,23 @@ func TestHashFromAlgo(t *testing.T) { }) } } + +func TestTransform(t *testing.T) { + c := qt.New(t) + + spec, err := htesting.NewTestResourceSpec() + c.Assert(err, qt.IsNil) + client := New(spec) + + r, err := htesting.NewResourceTransformerForSpec(spec, "hugo.txt", "Hugo Rocks!") + c.Assert(err, qt.IsNil) + + transformed, err := client.Fingerprint(r, "") + + c.Assert(err, qt.IsNil) + c.Assert(transformed.RelPermalink(), qt.Equals, "/hugo.a5ad1c6961214a55de53c1ce6e60d27b6b761f54851fa65e33066460dfa6a0db.txt") + c.Assert(transformed.Data(), qt.DeepEquals, map[string]interface{}{"Integrity": template.HTMLAttr("sha256-pa0caWEhSlXeU8HObmDSe2t2H1SFH6ZeMwZkYN+moNs=")}) + content, err := transformed.(resource.ContentProvider).Content() + c.Assert(err, qt.IsNil) + c.Assert(content, qt.Equals, "Hugo Rocks!") +} |