Skip to content

Commit

Permalink
feat: add maximum image file size to be processed by the thumbnailer
Browse files Browse the repository at this point in the history
  • Loading branch information
DeepDiver1975 committed May 3, 2024
1 parent 5f67abd commit e1abd8c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 22 deletions.
21 changes: 11 additions & 10 deletions services/thumbnails/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ type FileSystemStorage struct {

// Thumbnail defines the available thumbnail related configuration.
type Thumbnail struct {
Resolutions []string `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS" desc:"The supported list of target resolutions in the format WidthxHeight like 32x32. You can define any resolution as required. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
FileSystemStorage FileSystemStorage `yaml:"filesystem_storage"`
WebdavAllowInsecure bool `yaml:"webdav_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_WEBDAVSOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the webdav source." introductionVersion:"pre5.0"`
CS3AllowInsecure bool `yaml:"cs3_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_CS3SOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the CS3 source." introductionVersion:"pre5.0"`
RevaGateway string `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" introductionVersion:"pre5.0"`
FontMapFile string `yaml:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font file for txt thumbnails." introductionVersion:"pre5.0"`
TransferSecret string `yaml:"transfer_secret" env:"THUMBNAILS_TRANSFER_TOKEN" desc:"The secret to sign JWT to download the actual thumbnail file." introductionVersion:"pre5.0"`
DataEndpoint string `yaml:"data_endpoint" env:"THUMBNAILS_DATA_ENDPOINT" desc:"The HTTP endpoint where the actual thumbnail file can be downloaded." introductionVersion:"pre5.0"`
MaxInputWidth int `yaml:"max_input_width" env:"THUMBNAILS_MAX_INPUT_WIDTH" desc:"The maximum width of an input image which is being processed." introductionVersion:"6.0"`
MaxInputHeight int `yaml:"max_input_height" env:"THUMBNAILS_MAX_INPUT_HEIGHT" desc:"The maximum height of an input image which is being processed." introductionVersion:"6.0"`
Resolutions []string `yaml:"resolutions" env:"THUMBNAILS_RESOLUTIONS" desc:"The supported list of target resolutions in the format WidthxHeight like 32x32. You can define any resolution as required. See the Environment Variable Types description for more details." introductionVersion:"pre5.0"`
FileSystemStorage FileSystemStorage `yaml:"filesystem_storage"`
WebdavAllowInsecure bool `yaml:"webdav_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_WEBDAVSOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the webdav source." introductionVersion:"pre5.0"`
CS3AllowInsecure bool `yaml:"cs3_allow_insecure" env:"OCIS_INSECURE;THUMBNAILS_CS3SOURCE_INSECURE" desc:"Ignore untrusted SSL certificates when connecting to the CS3 source." introductionVersion:"pre5.0"`
RevaGateway string `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" introductionVersion:"pre5.0"`
FontMapFile string `yaml:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE" desc:"The path to a font file for txt thumbnails." introductionVersion:"pre5.0"`
TransferSecret string `yaml:"transfer_secret" env:"THUMBNAILS_TRANSFER_TOKEN" desc:"The secret to sign JWT to download the actual thumbnail file." introductionVersion:"pre5.0"`
DataEndpoint string `yaml:"data_endpoint" env:"THUMBNAILS_DATA_ENDPOINT" desc:"The HTTP endpoint where the actual thumbnail file can be downloaded." introductionVersion:"pre5.0"`
MaxInputWidth int `yaml:"max_input_width" env:"THUMBNAILS_MAX_INPUT_WIDTH" desc:"The maximum width of an input image which is being processed." introductionVersion:"6.0"`
MaxInputHeight int `yaml:"max_input_height" env:"THUMBNAILS_MAX_INPUT_HEIGHT" desc:"The maximum height of an input image which is being processed." introductionVersion:"6.0"`
MaxInputImageFileSize uint64 `yaml:"max_input_image_file_size" env:"THUMBNAILS_MAX_INPUT_IMAGE_FILE_SIZE" desc:"The maximum file size of an input image which is being processed." introductionVersion:"6.0"`
}
13 changes: 7 additions & 6 deletions services/thumbnails/pkg/config/defaults/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ func DefaultConfig() *config.Config {
FileSystemStorage: config.FileSystemStorage{
RootDirectory: path.Join(defaults.BaseDataPath(), "thumbnails"),
},
WebdavAllowInsecure: false,
RevaGateway: shared.DefaultRevaConfig().Address,
CS3AllowInsecure: false,
DataEndpoint: "http://127.0.0.1:9186/thumbnails/data",
MaxInputWidth: 7680,
MaxInputHeight: 4320,
WebdavAllowInsecure: false,
RevaGateway: shared.DefaultRevaConfig().Address,
CS3AllowInsecure: false,
DataEndpoint: "http://127.0.0.1:9186/thumbnails/data",
MaxInputWidth: 7680,
MaxInputHeight: 4320,
MaxInputImageFileSize: 50 * 1024 * 1024,
},
}
}
Expand Down
21 changes: 17 additions & 4 deletions services/thumbnails/pkg/thumbnail/imgsource/cs3.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ const (

// CS3 implements a CS3 image source
type CS3 struct {
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
insecure bool
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
insecure bool
maxImageFileSize uint64
}

// NewCS3Source configures a new CS3 image source
func NewCS3Source(cfg config.Thumbnail, gatewaySelector pool.Selectable[gateway.GatewayAPIClient]) CS3 {
return CS3{
gatewaySelector: gatewaySelector,
insecure: cfg.CS3AllowInsecure,
gatewaySelector: gatewaySelector,
insecure: cfg.CS3AllowInsecure,
maxImageFileSize: cfg.MaxInputImageFileSize,
}
}

Expand All @@ -60,6 +62,17 @@ func (s CS3) Get(ctx context.Context, path string) (io.ReadCloser, error) {
if err != nil {
return nil, err
}
stat, err := gwc.Stat(ctx, &provider.StatRequest{Ref: &ref})
if err != nil {
return nil, err
}
if stat.GetStatus().GetCode() != rpc.Code_CODE_OK {
return nil, fmt.Errorf("could not stat image: %s", stat.GetStatus().GetMessage())
}
if stat.GetInfo().GetSize() > s.maxImageFileSize {
return nil, errors.ErrImageTooLarge
}

rsp, err := gwc.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: &ref})

if err != nil {
Expand Down
21 changes: 19 additions & 2 deletions services/thumbnails/pkg/thumbnail/imgsource/webdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ import (
_ "image/png" // Import the png package so that image.Decode can understand pngs
"io"
"net/http"
"strconv"

"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
thumbnailerErrors "github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
"github.com/pkg/errors"
)

// NewWebDavSource creates a new webdav instance.
func NewWebDavSource(cfg config.Thumbnail) WebDav {
return WebDav{
insecure: cfg.WebdavAllowInsecure,
insecure: cfg.WebdavAllowInsecure,
maxImageFileSize: cfg.MaxInputImageFileSize,
}
}

// WebDav implements the Source interface for webdav services
type WebDav struct {
insecure bool
insecure bool
maxImageFileSize uint64
}

// Get downloads the file from a webdav service
Expand Down Expand Up @@ -53,5 +57,18 @@ func (s WebDav) Get(ctx context.Context, url string) (io.ReadCloser, error) {
return nil, fmt.Errorf("could not get the image \"%s\". Request returned with statuscode %d ", url, resp.StatusCode)
}

contentLength := resp.Header.Get("Content-Length")
if contentLength == "" {
// TODO: perform propfind on the resource
} else {
c, err := strconv.ParseUint(contentLength, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, `could not parse content length of webdav response "%s"`, url)
}
if c > s.maxImageFileSize {
return nil, thumbnailerErrors.ErrImageTooLarge
}
}

return resp.Body, nil
}

0 comments on commit e1abd8c

Please sign in to comment.