)
// XXHashFromReader calculates the xxHash for the given reader.
-func XXHashFromReader(r io.ReadSeeker) (uint64, int64, error) {
+func XXHashFromReader(r io.Reader) (uint64, int64, error) {
h := getXxHashReadFrom()
defer putXxHashReadFrom(h)
"fmt"
"math"
"strings"
+ "sync"
"testing"
qt "github.com/frankban/quicktest"
c.Assert(got, qt.Equals, uint64(7148569436472236994))
}
+func TestXxHashFromReaderPara(t *testing.T) {
+ c := qt.New(t)
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ i := i
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for j := 0; j < 100; j++ {
+ s := strings.Repeat("Hello ", i+j+1*42)
+ r := strings.NewReader(s)
+ got, size, err := XXHashFromReader(r)
+ c.Assert(size, qt.Equals, int64(len(s)))
+ c.Assert(err, qt.IsNil)
+ expect, _ := XXHashFromString(s)
+ c.Assert(got, qt.Equals, expect)
+ }
+ }()
+ }
+
+ wg.Wait()
+}
+
func TestXxHashFromString(t *testing.T) {
c := qt.New(t)
s := "Hello World"
b.AssertFileExists("public/de/mybundle/pixel.png", true)
b.AssertFileExists("public/en/mybundle/pixel.png", true)
- b.AssertFileExists("public/de/mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_2x2_resize_box_3.png", true)
+ b.AssertFileExists("public/de/mybundle/pixel_hu8581513846771248023.png", true)
// failing test below
- b.AssertFileExists("public/en/mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_2x2_resize_box_3.png", true)
+ b.AssertFileExists("public/en/mybundle/pixel_hu8581513846771248023.png", true)
}
func TestMultihostResourceOneBaseURLWithSuPath(t *testing.T) {
b.Build(BuildCfg{})
- b.AssertFileContent("public/index.html", "SUNSET FOR: en: /bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg/200/Lat: 36.59744166666667")
- b.AssertFileContent("public/fr/index.html", "SUNSET FOR: fr: /bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg/200/Lat: 36.59744166666667")
- b.AssertFileContent("public/index.html", " SUNSET2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg/123/Lat: 36.59744166666667")
- b.AssertFileContent("public/nn/index.html", " SUNSET2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg/123/Lat: 36.59744166666667")
+ b.AssertFileContent("public/index.html", "SUNSET FOR: en: /bundle/sunset_hu13235715490294913361.jpg/200/Lat: 36.59744166666667")
+ b.AssertFileContent("public/fr/index.html", "SUNSET FOR: fr: /bundle/sunset_hu13235715490294913361.jpg/200/Lat: 36.59744166666667")
+ b.AssertFileContent("public/index.html", " SUNSET2: /images/sunset_hu1573057890424052540.jpg/123/Lat: 36.59744166666667")
+ b.AssertFileContent("public/nn/index.html", " SUNSET2: /images/sunset_hu1573057890424052540.jpg/123/Lat: 36.59744166666667")
- b.AssertImage(200, 200, "public/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg")
+ b.AssertImage(200, 200, "public/bundle/sunset_hu13235715490294913361.jpg")
// Check the file cache
- b.AssertImage(200, 200, "resources/_gen/images/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg")
+ b.AssertImage(200, 200, "resources/_gen/images/bundle/sunset_hu13235715490294913361.jpg")
- b.AssertFileContent("resources/_gen/images/bundle/sunset_2020904703097093419.json",
+ b.AssertFileContent("resources/_gen/images/bundle/sunset_17710516992648092201.json",
"FocalLengthIn35mmFormat|uint16", "PENTAX")
- b.AssertImage(123, 234, "resources/_gen/images/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg")
-
- b.AssertFileContent("resources/_gen/images/images/sunset_2020904703097093419.json",
+ b.AssertFileContent("resources/_gen/images/images/sunset_17710516992648092201.json",
"FocalLengthIn35mmFormat|uint16", "PENTAX")
b.AssertNoDuplicateWrites()
"RelPermalink: /docs/p1/sub/mymixcasetext2.txt|Name: sub/mymixcasetext2.txt|",
"RelPermalink: /mydata.yaml|Name: sub/data1.yaml|Title: Sub data|Params: map[]|",
"Featured Image: /a/pixel.png|featured.png|",
- "Resized Featured Image: /a/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_10x10_resize_box_3.png|10|",
+ "Resized Featured Image: /a/pixel_hu16809842526914527184.png|10|",
// Resource from string
"RelPermalink: /docs/p1/mytext.txt|Name: textresource|Title: My Text Resource|Params: map[param1:param1v]|",
// Dates
b.AssertFileContent("public/index.html",
fmt.Sprintf(`
SUNSET: /images/sunset.jpg|/images/sunset.a9bf1d944e19c0f382e0d8f51de690f7d0bc8fa97390c4242a86c3e5c0737e71.jpg|900|90587
-FIT: /images/sunset.jpg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_fit_q75_box.jpg|200
+FIT: /images/sunset.jpg|/images/sunset_hu15210517121918042184.jpg|200
CSS integrity Data first: sha256-od9YaHw8nMOL8mUy97Sy8sKwMV3N4hI3aVmZXATxH+8= /styles.min.a1df58687c3c9cc38bf26532f7b4b2f2c2b0315dcde212376959995c04f11fef.css
CSS integrity Data last: /styles2.min.1cfc52986836405d37f9998a63fd6dd8608e8c410e5e3db1daaa30f78bc273ba.css sha256-HPxSmGg2QF03+ZmKY/1t2GCOjEEOXj2x2qow94vCc7o=
SUNSET REMOTE: /sunset_%[1]s.jpg|/sunset_%[1]s.a9bf1d944e19c0f382e0d8f51de690f7d0bc8fa97390c4242a86c3e5c0737e71.jpg|900|90587
-FIT REMOTE: /sunset_%[1]s.jpg|/sunset_%[1]s_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_fit_q75_box.jpg|200
+FIT REMOTE: /sunset_%[1]s.jpg|/sunset_%[1]s_hu15210517121918042184.jpg|200
REMOTE NOT FOUND: OK
LOCAL NOT FOUND: OK
PRINT PROTOCOL ERROR DETAILS: Err: error calling resources.GetRemote: Get "gopher://example.org": unsupported protocol scheme "gopher"||
if conf.TargetFormat != i.Format {
p2 = conf.TargetFormat.DefaultExtension()
}
-
- h := i.hash()
- idStr := fmt.Sprintf("_hu%d_%d", h, i.size())
-
- // Do not change for no good reason.
- const md5Threshold = 100
-
- key := conf.GetKey(i.Format)
-
- // It is useful to have the key in clear text, but when nesting transforms, it
- // can easily be too long to read, and maybe even too long
- // for the different OSes to handle.
- if len(p1)+len(idStr)+len(p2) > md5Threshold {
- key = hashing.MD5FromStringHexEncoded(p1 + key + p2)
- huIdx := strings.Index(p1, "_hu")
- if huIdx != -1 {
- p1 = p1[:huIdx]
- } else {
- // This started out as a very long file name. Making it even longer
- // could melt ice in the Arctic.
- p1 = ""
- }
- } else if strings.Contains(p1, idStr) {
- // On scaling an already scaled image, we get the file info from the original.
- // Repeating the same info in the filename makes it stuttery for no good reason.
- idStr = ""
+ const prefix = "_hu"
+ huIdx := strings.LastIndex(p1, prefix)
+ incomingID := "i"
+ if huIdx > -1 {
+ incomingID = p1[huIdx+len(prefix):]
+ p1 = p1[:huIdx]
}
-
+ hash := hashing.HashUint64(incomingID, i.hash(), conf.GetKey(i.Format))
rp := i.getResourcePaths()
- rp.File = fmt.Sprintf("%s%s_%s%s", p1, idStr, key, p2)
+ rp.File = fmt.Sprintf("%s%s%d%s", p1, prefix, hash, p2)
return rp
}
resized, err := image.Resize("123x")
c.Assert(err, qt.IsNil)
c.Assert(image.MediaType(), qt.Equals, media.Builtin.WEBPType)
- c.Assert(resized.RelPermalink(), qt.Equals, "/a/sunrise_hu6ad68bcbae1b79cbc2f6b451894deaf6_95652_123x0_resize_q68_h2_linear_2.webp")
+ c.Assert(resized.RelPermalink(), qt.Equals, "/a/sunrise_hu544374262273649331.webp")
c.Assert(resized.Width(), qt.Equals, 123)
}
assertWidthHeight(resizedAndRotated, 125, 200)
assertWidthHeight(resized, 300, 200)
- c.Assert(resized.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_300x200_resize_q68_linear.jpg")
+ c.Assert(resized.RelPermalink(), qt.Equals, "/a/sunset_hu2082030801149749592.jpg")
fitted, err := resized.Fit("50x50")
c.Assert(err, qt.IsNil)
- c.Assert(fitted.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_625708021e2bb281c9f1002f88e4753f.jpg")
+ c.Assert(fitted.RelPermalink(), qt.Equals, "/a/sunset_hu16263619592447877226.jpg")
assertWidthHeight(fitted, 50, 33)
// Check the MD5 key threshold
fittedAgain, _ := fitted.Fit("10x20")
fittedAgain, err = fittedAgain.Fit("10x20")
c.Assert(err, qt.IsNil)
- c.Assert(fittedAgain.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_3f65ba24dc2b7fba0f56d7f104519157.jpg")
+ c.Assert(fittedAgain.RelPermalink(), qt.Equals, "/a/sunset_hu847809310637164306.jpg")
assertWidthHeight(fittedAgain, 10, 7)
filled, err := image.Fill("200x100 bottomLeft")
c.Assert(err, qt.IsNil)
- c.Assert(filled.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_bottomleft.jpg")
+ c.Assert(filled.RelPermalink(), qt.Equals, "/a/sunset_hu18289448341423092707.jpg")
assertWidthHeight(filled, 200, 100)
smart, err := image.Fill("200x100 smart")
c.Assert(err, qt.IsNil)
- c.Assert(smart.RelPermalink(), qt.Equals, fmt.Sprintf("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_smart%d.jpg", 1))
+ c.Assert(smart.RelPermalink(), qt.Equals, "/a/sunset_hu11649371610839769766.jpg")
assertWidthHeight(smart, 200, 100)
// Check cache
cropped, err := image.Crop("300x300 topRight")
c.Assert(err, qt.IsNil)
- c.Assert(cropped.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_300x300_crop_q68_linear_topright.jpg")
+ c.Assert(cropped.RelPermalink(), qt.Equals, "/a/sunset_hu2242042514052853140.jpg")
assertWidthHeight(cropped, 300, 300)
smartcropped, err := image.Crop("200x200 smart")
c.Assert(err, qt.IsNil)
- c.Assert(smartcropped.RelPermalink(), qt.Equals, fmt.Sprintf("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_crop_q68_linear_smart%d.jpg", 1))
+ c.Assert(smartcropped.RelPermalink(), qt.Equals, "/a/sunset_hu12983255101170993571.jpg")
assertWidthHeight(smartcropped, 200, 200)
// Check cache
imagePng, err := image.Resize("450x png")
c.Assert(err, qt.IsNil)
- c.Assert(imagePng.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_450x0_resize_linear.png")
+ c.Assert(imagePng.RelPermalink(), qt.Equals, "/a/sunset_hu11737890885216583918.png")
c.Assert(imagePng.ResourceType(), qt.Equals, "image")
assertExtWidthHeight(imagePng, ".png", 450, 281)
c.Assert(imagePng.Name(), qt.Equals, "sunset.jpg")
imageGif, err := image.Resize("225x gif")
c.Assert(err, qt.IsNil)
- c.Assert(imageGif.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_225x0_resize_linear.gif")
+ c.Assert(imageGif.RelPermalink(), qt.Equals, "/a/sunset_hu1431827106749674475.gif")
c.Assert(imageGif.ResourceType(), qt.Equals, "image")
assertExtWidthHeight(imageGif, ".gif", 225, 141)
c.Assert(imageGif.Name(), qt.Equals, "sunset.jpg")
}()
check1 := func(img images.ImageResource) {
- resizedLink := "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_100x50_resize_q75_box.jpg"
+ resizedLink := "/a/sunset_hu7919355342577096259.jpg"
c.Assert(img.RelPermalink(), qt.Equals, resizedLink)
assertImageFile(c, spec.PublishFs, resizedLink, 100, 50)
}
c.Assert(err, qt.IsNil)
c.Assert(resized, qt.Not(qt.IsNil))
c.Assert(resized.Width(), qt.Equals, 200)
- c.Assert(resized.RelPermalink(), qt.Equals, "/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_65b757a6e14debeae720fe8831f0a9bc.jpg")
+ c.Assert(resized.RelPermalink(), qt.Equals, "/a/1234567890qwertyuiopasdfghjklzxcvbnm5to6eeeeee7via8eleph_hu9514381480012510326.jpg")
resized, err = resized.Resize("100x")
c.Assert(err, qt.IsNil)
c.Assert(resized, qt.Not(qt.IsNil))
c.Assert(resized.Width(), qt.Equals, 100)
- c.Assert(resized.RelPermalink(), qt.Equals, "/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_c876768085288f41211f768147ba2647.jpg")
+ c.Assert(resized.RelPermalink(), qt.Equals, "/a/1234567890qwertyuiopasdfghjklzxcvbnm5to6eeeeee7via8eleph_hu1776700126481066216.jpg")
})
// Issue #6137
resized, err := image.Resize("800x")
c.Assert(err, qt.IsNil)
c.Assert(resized.MediaType().Type, qt.Equals, "image/png")
- c.Assert(resized.RelPermalink(), qt.Equals, "/a/gohugoio_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_800x0_resize_linear_3.png")
+ c.Assert(resized.RelPermalink(), qt.Equals, "/a/gohugoio_hu8582372628235034388.png")
c.Assert(resized.Width(), qt.Equals, 800)
}
if !goldenEqual(nrgba1, nrgba2) {
switch fi1.Name() {
- case "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_73c19c5f80881858a85aa23cd0ca400d.png",
- "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_ae631e5252bb5d7b92bc766ad1a89069.png",
- "gohugoio8_hu7f72c00afdf7634587afaa5eff2a25b2_73538_d1bbfa2629bffb90118cacce3fcfb924.png",
- "giphy_hu3eafc418e52414ace6236bf1d31f82e1_52213_200x0_resize_box_1.gif":
+ case "giphy_hu13007323561585908901.gif",
+ "gohugoio8_hu12690451569630232821.png",
+ "gohugoio8_hu1619987041333606118.png",
+ "gohugoio8_hu18164141965527013334.png":
c.Log("expectedly differs from golden due to dithering:", fi1.Name())
default:
c.Errorf("resulting image differs from golden: %s", fi1.Name())
files := `
-- config.toml --
+disableLiveReload = true
baseURL = "https://example.org"
-- content/mybundle/index.md --
---
assertImages := func() {
b.AssertFileContent("public/index.html", `
- gif: /mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_1x2_resize_box_3.gif|}|1|2|image/gif|
- bmp: /mybundle/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_2x3_resize_box_3.bmp|}|2|3|image/bmp|
- anigif: /mybundle/giphy_hu3eafc418e52414ace6236bf1d31f82e1_52213_4x5_resize_box_1.gif|4|5|image/gif|
+ gif: /mybundle/pixel_hu14657638653019978294.gif|}|1|2|image/gif|
+ bmp: /mybundle/pixel_hu14705577916774115224.bmp|}|2|3|image/bmp|
+ anigif: /mybundle/giphy_hu3665406585348417395.gif|4|5|image/gif|
`)
}
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html",
- "jpg|RelPermalink: /images/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_filter_1397118720664523257.jpg|MediaType: image/jpeg|Width: 1|Height: 1|",
- "resize 1|RelPermalink: /images/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_filter_3796633496882814163.jpg|MediaType: image/jpeg|Width: 20|Height: 30|",
- "resize 2|RelPermalink: /images/pixel_hu8aa3346827e49d756ff4e630147c42b5_70_filter_3796633496882814163.jpg|MediaType: image/jpeg|Width: 20|Height: 30|",
+ "jpg|RelPermalink: /images/pixel_hu13683954895608450100.jpg|MediaType: image/jpeg|Width: 1|Height: 1|",
+ "resize 1|RelPermalink: /images/pixel_hu3453403302435331853.jpg|MediaType: image/jpeg|Width: 20|Height: 30|",
+ "resize 2|RelPermalink: /images/pixel_hu3453403302435331853.jpg|MediaType: image/jpeg|Width: 20|Height: 30|",
)
}
resizedPublished1, err := img.Resize("40x40")
c.Assert(err, qt.IsNil)
c.Assert(resizedPublished1.Height(), qt.Equals, 40)
- c.Assert(resizedPublished1.RelPermalink(), qt.Equals, "/gopher.changed_hu2e827f5a78333ebc04166dd643235dea_1462_40x40_resize_linear_3.png")
- assertShouldExist(c, spec, "public/gopher.changed_hu2e827f5a78333ebc04166dd643235dea_1462_40x40_resize_linear_3.png", true)
+ c.Assert(resizedPublished1.RelPermalink(), qt.Equals, "/gopher.changed_hu16988682630555427117.png")
+ assertShouldExist(c, spec, "public/gopher.changed_hu16988682630555427117.png", true)
// Permalink called.
resizedPublished2, err := img.Resize("30x30")
c.Assert(err, qt.IsNil)
c.Assert(resizedPublished2.Height(), qt.Equals, 30)
- c.Assert(resizedPublished2.Permalink(), qt.Equals, "https://example.com/gopher.changed_hu2e827f5a78333ebc04166dd643235dea_1462_30x30_resize_linear_3.png")
- assertShouldExist(c, spec, "public/gopher.changed_hu2e827f5a78333ebc04166dd643235dea_1462_30x30_resize_linear_3.png", true)
+ c.Assert(resizedPublished2.Permalink(), qt.Equals, "https://example.com/gopher.changed_hu14141325020798305104.png")
+ assertShouldExist(c, spec, "public/gopher.changed_hu14141325020798305104.png", true)
// Not published because none of RelPermalink or Permalink was called.
resizedNotPublished, err := img.Resize("50x50")
b.AssertFileContent("public/index.html", `
Image Orig: /blog/images/pixel.png|image/png|1|1|
-Image Copy1: /blog/images/copy_hu8aa3346827e49d756ff4e630147c42b5_70_3x4_resize_box_3.png|image/png|3|4|
+Image Copy1: /blog/images/copy_hu2891316072287293157.png|image/png|3|4|
Image Copy2: /blog/images/copy2.png|image/png|3|4
Image Copy3: image/png|3|4|
Orig: /blog/js/foo.js|text/javascript|let foo;|