From a848c0f49aecee9a6e246f3793da6ff45575e4a1 Mon Sep 17 00:00:00 2001
From: Patrice Tisserand
Date: Sun, 11 Nov 2018 23:13:48 +0100
Subject: [PATCH] Added support to resize remote image: #16
A path is 'remote' if net.url.Parse(path).Scheme is not empty.
TwoTier.RemoteLocalPath convert URL to local path which is then use for storage,cache and thumbnails.
---
api/api.go | 2 +-
api/routes.go | 3 ++-
store/twotier.go | 45 +++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/api/api.go b/api/api.go
index 37e21fb..973b11e 100644
--- a/api/api.go
+++ b/api/api.go
@@ -68,7 +68,7 @@ func NewApi(ready chan<- bool) *Api {
Thumbnails: thumbCache,
Tiers: collections.NewSyncStrSet(),
Etags: etags,
- Router: mux.NewRouter().StrictSlash(true),
+ Router: mux.NewRouter().StrictSlash(true).SkipClean(true),
}
go api.initCacheLoader(ready)
api.initCacheManager()
diff --git a/api/routes.go b/api/routes.go
index 65104b0..fcd82f8 100644
--- a/api/routes.go
+++ b/api/routes.go
@@ -93,7 +93,8 @@ func (api *Api) serveThumbs() http.HandlerFunc {
vars["resizeOp"],
vars["options"])
path := vars["path"]
- thumbPath := resizeTier + "/" + path
+ thumbPath, _ := api.Originals.RemoteToLocalPath(path)
+ thumbPath = resizeTier + "/" + thumbPath
api.Tiers.Add(resizeTier)
thumbBuf, _ := api.Thumbnails.Get(thumbPath)
if thumbBuf == nil {
diff --git a/store/twotier.go b/store/twotier.go
index d016f05..8beffd7 100644
--- a/store/twotier.go
+++ b/store/twotier.go
@@ -1,20 +1,46 @@
package store
+import (
+ "errors"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "path/filepath"
+)
+
type TwoTier struct {
Store Store
Cache Cache
}
-func (s *TwoTier) Get(filename string) ([]byte, error) {
+func (s *TwoTier) Get(aurl string) ([]byte, error) {
var buf []byte
var err error
+ filename, isRemote := s.RemoteToLocalPath(aurl)
+
if s.Cache != nil {
buf, _ = s.Cache.Get(filename)
}
if buf == nil {
buf, err = s.Store.Get(filename)
if err != nil {
- return nil, err
+ if !isRemote {
+ return nil, err
+ } else {
+ response, err := http.Get(aurl)
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode >= 400 {
+ return nil, errors.New("(" + response.Request.URL.String() + ") HTTP Error: " + response.Status)
+ }
+ defer response.Body.Close()
+ buf, err = ioutil.ReadAll(response.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = s.Store.Put(filename, buf)
+ }
}
if s.Cache != nil {
go s.Cache.Put(filename, buf)
@@ -54,3 +80,18 @@ func (s *TwoTier) LoadCache(walkFn func(item interface{}) error) error {
}
return s.Cache.LoadCache(walkFn)
}
+
+func (s *TwoTier) RemoteToLocalPath(path string) (string, bool) {
+ var localPath string
+ var isRemote bool
+
+ aurl, _ := url.Parse(path)
+ if aurl.Scheme != "" {
+ isRemote = true
+ localPath = filepath.Join(aurl.Hostname(), aurl.EscapedPath())
+ } else {
+ isRemote = false
+ localPath = path
+ }
+ return localPath, isRemote
+}