move cachedImgID and sha1Str from rest.proxy to store.image

This commit is contained in:
Dmitry Verkhoturov
2020-04-24 14:16:01 -05:00
committed by Umputun
parent 4b26b8e259
commit b71e0be095
4 changed files with 33 additions and 22 deletions
+1 -21
View File
@@ -3,13 +3,10 @@ package proxy
import (
"bytes"
"context"
"crypto/sha1" //nolint:gosec // not used for cryptography
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
@@ -92,7 +89,7 @@ func (p Image) Handler(w http.ResponseWriter, r *http.Request) {
imgURL := string(src)
var img []byte
imgID, err := cachedImgID(imgURL)
imgID, err := image.CachedImgID(imgURL)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't parse image url "+imgURL, rest.ErrAssetNotFound)
return
@@ -174,20 +171,3 @@ func (p Image) downloadImage(ctx context.Context, imgURL string) ([]byte, error)
}
return imgData, nil
}
func sha1Str(s string) string {
return fmt.Sprintf("%x", sha1.Sum([]byte(s))) //nolint:gosec // not used for cryptography
}
// generates ID for a cached image.
// ID would look like: "cached_images/<sha1-of-image-url-hostname>-<sha1-of-image-entire-url>"
// <sha1-of-image-url-hostname> - would allow us to identify all images from particular site if ever needed
// <sha1-of-image-entire-url> - would allow us to avoid storing duplicates of the same image
// (as accurate as deduplication based on potentially mutable url can be)
func cachedImgID(imgURL string) (string, error) {
parsedURL, err := url.Parse(imgURL)
if err != nil {
return "", errors.Wrapf(err, "can parse url %s", imgURL)
}
return fmt.Sprintf("cached_images/%s-%s", sha1Str(parsedURL.Hostname()), sha1Str(imgURL)), nil
}
+1 -1
View File
@@ -186,7 +186,7 @@ func TestImage_RoutesCachingImage(t *testing.T) {
assert.Equal(t, "image/png", resp.Header["Content-Type"][0])
imageStore.AssertCalled(t, "Load", mock.Anything)
imageStore.AssertCalled(t, "Save", "cached_images/4b84b15bff6ee5796152495a230e45e3d7e947d9-"+sha1Str(imgURL), gopherPNGBytes())
imageStore.AssertCalled(t, "Save", "cached_images/4b84b15bff6ee5796152495a230e45e3d7e947d9-"+image.Sha1Str(imgURL), gopherPNGBytes())
imageStore.AssertCalled(t, "Commit", mock.Anything)
}
+21
View File
@@ -8,6 +8,8 @@ package image
import (
"bytes"
"context"
"crypto/sha1" //nolint:gosec // not used for cryptography
"fmt"
"image"
// support gif and jpeg images decoding
_ "image/gif"
@@ -16,6 +18,7 @@ import (
"io"
"io/ioutil"
"net/http"
"net/url"
"path"
"strings"
"sync"
@@ -323,3 +326,21 @@ func readAndValidateImage(r io.Reader, maxSize int) ([]byte, error) {
func guid() string {
return xid.New().String()
}
// Sha1Str converts provided string to sha1
func Sha1Str(s string) string {
return fmt.Sprintf("%x", sha1.Sum([]byte(s))) //nolint:gosec // not used for cryptography
}
// CachedImgID generates ID for a cached image.
// ID would look like: "cached_images/<sha1-of-image-url-hostname>-<sha1-of-image-entire-url>"
// <sha1-of-image-url-hostname> - would allow us to identify all images from particular site if ever needed
// <sha1-of-image-entire-url> - would allow us to avoid storing duplicates of the same image
// (as accurate as deduplication based on potentially mutable url can be)
func CachedImgID(imgURL string) (string, error) {
parsedURL, err := url.Parse(imgURL)
if err != nil {
return "", errors.Wrapf(err, "can parse url %s", imgURL)
}
return fmt.Sprintf("cached_images/%s-%s", Sha1Str(parsedURL.Hostname()), Sha1Str(imgURL)), nil
}
+10
View File
@@ -217,3 +217,13 @@ func TestGetProportionalSizes(t *testing.T) {
})
}
}
func TestCachedImgID(t *testing.T) {
img, err := CachedImgID(" http://foo.com")
assert.Error(t, err)
assert.Empty(t, img)
imgURL := "http://example.org/img/1.png"
img, err = CachedImgID(imgURL)
assert.NoError(t, err)
assert.Equal(t, "cached_images/"+Sha1Str("example.org")+"-"+Sha1Str(imgURL), img)
}