diff --git a/proxy/data.go b/proxy/data.go index bf184fd..cbe3d86 100644 --- a/proxy/data.go +++ b/proxy/data.go @@ -61,27 +61,9 @@ func (o Options) String() string { func ParseOptions(str string) *Options { o := new(Options) - var h, w string parts := strings.Split(str, ",") - - // parse size - size := strings.SplitN(parts[0], "x", 2) - w = size[0] - if len(size) > 1 { - h = size[1] - } else { - h = w - } - - if w != "" { - o.Width, _ = strconv.ParseFloat(w, 64) - } - if h != "" { - o.Height, _ = strconv.ParseFloat(h, 64) - } - - for _, part := range parts[1:] { + for _, part := range parts { if part == "fit" { o.Fit = true continue @@ -95,10 +77,35 @@ func ParseOptions(str string) *Options { continue } - if len(part) > 2 && strings.HasPrefix(part, "r") { + if len(part) > 2 && part[:1] == "r" { o.Rotate, _ = strconv.Atoi(part[1:]) continue } + + if strings.ContainsRune(part, 'x') { + var h, w string + size := strings.SplitN(part, "x", 2) + w = size[0] + if len(size) > 1 { + h = size[1] + } else { + h = w + } + + if w != "" { + o.Width, _ = strconv.ParseFloat(w, 64) + } + if h != "" { + o.Height, _ = strconv.ParseFloat(h, 64) + } + continue + } + + if size, err := strconv.ParseFloat(part, 64); err == nil { + o.Width = size + o.Height = size + continue + } } return o diff --git a/proxy/data_test.go b/proxy/data_test.go index 8bb69eb..054b147 100644 --- a/proxy/data_test.go +++ b/proxy/data_test.go @@ -46,6 +46,7 @@ func TestParseOptions(t *testing.T) { {"", emptyOptions}, {"x", emptyOptions}, {"0", emptyOptions}, + {",,,,", emptyOptions}, // size variations {"1x", &Options{Width: 1}}, @@ -54,12 +55,23 @@ func TestParseOptions(t *testing.T) { {"0.1x0.2", &Options{Width: 0.1, Height: 0.2}}, // additional flags - {",fit", &Options{Fit: true}}, - {",r90", &Options{Rotate: 90}}, - {",fv", &Options{FlipVertical: true}}, - {",fh", &Options{FlipHorizontal: true}}, + {"fit", &Options{Fit: true}}, + {"r90", &Options{Rotate: 90}}, + {"fv", &Options{FlipVertical: true}}, + {"fh", &Options{FlipHorizontal: true}}, + + // duplicate flags (last one wins) + {"1x2,3x4", &Options{Width: 3, Height: 4}}, + {"1x2,3", &Options{Width: 3, Height: 3}}, + {"1x2,0x3", &Options{Width: 0, Height: 3}}, + {"1x,x2", &Options{Width: 1, Height: 2}}, + {"r90,r270", &Options{Rotate: 270}}, + + // mix of valid and invalid flags + {"FOO,1,BAR,r90,BAZ", &Options{Width: 1, Height: 1, Rotate: 90}}, {"1x2,fit,r90,fv,fh", &Options{1, 2, true, 90, true, true}}, + {"r90,fh,1x2,fv,fit", &Options{1, 2, true, 90, true, true}}, } for i, tt := range tests { diff --git a/readme.md b/readme.md index 056e228..8171359 100644 --- a/readme.md +++ b/readme.md @@ -24,9 +24,10 @@ imageproxy URLs are of the form `http://localhost/{options}/{remote_url}`. ### Options ### -Options are specified as a comma delimited list of parameters, the first of -which always specifies image size. The format is a superset of [resize.ly's -options](https://resize.ly/#demo). +Options are specified as a comma delimited list of parameters, which can be +supplied in any order. Duplicate parameters overwrite previous values. + +The format is a superset of [resize.ly's options](https://resize.ly/#demo). #### Size ####