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 +}