Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 40 additions & 26 deletions thumbnails/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"io"
"net/http"
"net/url"
"path"
"path/filepath"
"strconv"
"strings"
Expand All @@ -45,6 +46,7 @@ import (
"github.com/cs3org/reva/v3/pkg/rhttp/global"
"github.com/cs3org/reva/v3/pkg/rhttp/router"
"github.com/cs3org/reva/v3/pkg/sharedconf"
"github.com/cs3org/reva/v3/pkg/spaces"
"github.com/cs3org/reva/v3/pkg/storage/utils/downloader"
"github.com/cs3org/reva/v3/pkg/utils/cfg"
"github.com/pkg/errors"
Expand Down Expand Up @@ -143,22 +145,53 @@ func New(ctx context.Context, m map[string]interface{}) (global.Service, error)
return s, nil
}

func (s *Thumbnails) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var head string

head, r.URL.Path = router.ShiftPath(r.URL.Path)
switch head {
case "files":
if !checkMethods(r, http.MethodGet) {
w.WriteHeader(http.StatusNotFound)
return
}
s.davUserContext(s.Thumbnail(w, r)).ServeHTTP(w, r)
case "public-files":
if !checkMethods(r, http.MethodGet, http.MethodHead) {
w.WriteHeader(http.StatusNotFound)
return
}
s.davPublicContext(s.Thumbnail(w, r)).ServeHTTP(w, r)
}
})
}

func (s *Thumbnails) davUserContext(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := appctx.GetLogger(ctx)

path := r.URL.Path
path, _ = url.PathUnescape(path)
urlPath, _ := url.PathUnescape(r.URL.Path)

storageSpaceID, resourcePath := router.ShiftPath(urlPath)
_, spacePath, ok := spaces.DecodeStorageSpaceID(storageSpaceID)
if !ok {
s.writeHTTPError(w, errtypes.NotFound(""))
return
}
resourcePath = path.Join(spacePath, resourcePath)

res, err := s.statRes(ctx, &provider.Reference{
Path: path,
Path: resourcePath,
})
if err != nil {
s.writeHTTPError(w, err)
return
}

ctx = ContextSetResource(ctx, res)
log.Info().Msgf("FindMe - set resource %s", res.Path)

next.ServeHTTP(w, r.WithContext(ctx))
})
Expand Down Expand Up @@ -365,12 +398,16 @@ func parseDimension(d, name string, defaultValue int) (int, error) {
func (s *Thumbnails) Thumbnail(w http.ResponseWriter, r *http.Request) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
thumbReq, err := s.parseThumbnailRequest(r)
log := appctx.GetLogger(r.Context())
log.Info().Msgf("FindMe - Handling thumbnail request %s", thumbReq.File)
if err != nil {
s.writeHTTPError(w, err)
return
}

data, mimetype, err := s.thumbnail.GetThumbnail(r.Context(), thumbReq.File, thumbReq.ETag, thumbReq.Width, thumbReq.Height, thumbReq.OutputType)
log.Info().Msgf("FindMe - Got thumbnail for %s", thumbReq.File)

if err != nil {
s.writeHTTPError(w, err)
return
Expand Down Expand Up @@ -402,29 +439,6 @@ func (s *Thumbnails) writeHTTPError(w http.ResponseWriter, err error) {
_, _ = w.Write([]byte(err.Error()))
}

func (s *Thumbnails) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var head string

head, r.URL.Path = router.ShiftPath(r.URL.Path)
switch head {
case "files":
if !checkMethods(r, http.MethodGet) {
w.WriteHeader(http.StatusNotFound)
return
}
s.davUserContext(s.Thumbnail(w, r)).ServeHTTP(w, r)
return
case "public-files":
if !checkMethods(r, http.MethodGet, http.MethodHead) {
w.WriteHeader(http.StatusNotFound)
return
}
s.davPublicContext(s.Thumbnail(w, r)).ServeHTTP(w, r)
}
})
}

func checkMethods(r *http.Request, methods ...string) bool {
for _, m := range methods {
if r.Method == m {
Expand Down
9 changes: 9 additions & 0 deletions thumbnails/manager/thumbnail.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ import (

// load all the cache drivers
_ "github.com/cernbox/reva-plugins/thumbnails/cache/loader"

_ "image/gif"
_ "image/jpeg"
_ "image/png"
)

// FileType is the output format of the thumbnail
Expand Down Expand Up @@ -106,23 +110,28 @@ func (t *Thumbnail) GetThumbnail(ctx context.Context, file, etag string, width,
defer r.Close()

img, _, err := image.Decode(r)
log.Debug().Err(err).Msgf("thumbnails: finished decoding %s", file)

if err != nil {
return nil, "", errors.Wrap(err, "thumbnails: error decoding file "+file)
}

resolution := image.Rect(0, 0, width, height)
match := t.fixedResolutions.MatchOrResize(resolution, img.Bounds())
thumb := imaging.Thumbnail(img, match.Dx(), match.Dy(), imaging.Linear)
log.Debug().Msgf("thumbnails: finished resize %s", file)

var buf bytes.Buffer
format, opts := t.getEncoderFormat(outType)
err = imaging.Encode(&buf, thumb, format, opts...)
if err != nil {
return nil, "", errors.Wrap(err, "thumbnails: error encoding image")
}
log.Debug().Msgf("thumbnails: finished re-encoding %s", file)

data := buf.Bytes()
err = t.cache.Set(file, etag, width, height, data)

if err != nil {
log.Warn().Msg("failed to save data into the cache")
} else {
Expand Down