httpimagestore 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/codeStyleSettings.xml +13 -0
- data/.idea/dictionaries/wcc.xml +8 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/httpimagestore.iml +69 -0
- data/.idea/jenkinsSettings.xml +9 -0
- data/.idea/misc.xml +5 -0
- data/.idea/modules.xml +9 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -4
- data/README.md +55 -33
- data/VERSION +1 -1
- data/bin/httpimagestore +19 -5
- data/features/cache-control.feature +8 -9
- data/features/compatibility.feature +46 -21
- data/features/error-reporting.feature +15 -16
- data/features/flexi.feature +4 -5
- data/features/health-check.feature +1 -2
- data/features/request-matching.feature +211 -0
- data/features/s3-store-and-thumbnail.feature +3 -10
- data/features/storage.feature +7 -9
- data/httpimagestore.gemspec +17 -5
- data/lib/httpimagestore/configuration/handler.rb +55 -30
- data/lib/httpimagestore/configuration/output.rb +51 -2
- data/spec/configuration_handler_spec.rb +4 -22
- data/spec/configuration_output_spec.rb +86 -2
- metadata +17 -5
|
@@ -8,18 +8,18 @@ Feature: S3 object Cache-Control header settings
|
|
|
8
8
|
"""
|
|
9
9
|
s3 key="@AWS_ACCESS_KEY_ID@" secret="@AWS_SECRET_ACCESS_KEY@" ssl=false
|
|
10
10
|
|
|
11
|
-
path "hash"
|
|
12
|
-
path "hash-name"
|
|
11
|
+
path "hash" "#{input_digest}.#{image_mime_extension}"
|
|
12
|
+
path "hash-name" "#{input_digest}-#{image_name}.#{image_mime_extension}"
|
|
13
13
|
|
|
14
14
|
put "thumbnail" {
|
|
15
15
|
thumbnail "input" {
|
|
16
|
-
"no-cache"
|
|
17
|
-
"cache"
|
|
16
|
+
"no-cache" operation="crop" width=128 height=128 format="jpeg"
|
|
17
|
+
"cache" operation="crop" width=256 height=256 format="jpeg"
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
store_s3 "input"
|
|
21
|
-
store_s3 "no-cache"
|
|
22
|
-
store_s3 "cache"
|
|
20
|
+
store_s3 "input" bucket="@AWS_S3_TEST_BUCKET@" public=true path="hash"
|
|
21
|
+
store_s3 "no-cache" bucket="@AWS_S3_TEST_BUCKET@" public=true path="hash-name"
|
|
22
|
+
store_s3 "cache" bucket="@AWS_S3_TEST_BUCKET@" public=true path="hash-name" cache-control="public, max-age=31557600, s-maxage=0"
|
|
23
23
|
}
|
|
24
24
|
"""
|
|
25
25
|
|
|
@@ -38,5 +38,4 @@ Feature: S3 object Cache-Control header settings
|
|
|
38
38
|
"""
|
|
39
39
|
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/4006450256177f4a.jpg Cache-Control header will not be set
|
|
40
40
|
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/4006450256177f4a-no-cache.jpg Cache-Control header will not be set
|
|
41
|
-
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/4006450256177f4a-cache.jpg Cache-Control header will be public, max-age=31557600, s-maxage=0
|
|
42
|
-
|
|
41
|
+
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/4006450256177f4a-cache.jpg Cache-Control header will be public, max-age=31557600, s-maxage=0
|
|
@@ -9,49 +9,63 @@ Feature: Image list based thumbnailing and S3 storage
|
|
|
9
9
|
"""
|
|
10
10
|
s3 key="@AWS_ACCESS_KEY_ID@" secret="@AWS_SECRET_ACCESS_KEY@" ssl=false
|
|
11
11
|
|
|
12
|
-
path "hash"
|
|
13
|
-
path "hash-name"
|
|
14
|
-
path "structured"
|
|
15
|
-
path "structured-name"
|
|
12
|
+
path "hash" "#{input_digest}.#{image_mime_extension}"
|
|
13
|
+
path "hash-name" "#{input_digest}/#{image_name}.#{image_mime_extension}"
|
|
14
|
+
path "structured" "#{dirname}/#{input_digest}/#{basename}.#{image_mime_extension}"
|
|
15
|
+
path "structured-name" "#{dirname}/#{input_digest}/#{basename}-#{image_name}.#{image_mime_extension}"
|
|
16
|
+
path "flexi-original" "#{hash}.jpg"
|
|
16
17
|
|
|
17
18
|
put "thumbnail" ":name_list" ":path/.+/" {
|
|
18
19
|
thumbnail "input" {
|
|
19
|
-
"small"
|
|
20
|
-
"tiny_png"
|
|
21
|
-
"bad"
|
|
20
|
+
"small" operation="crop" width=128 height=128 format="jpeg" if-image-name-on="#{name_list}"
|
|
21
|
+
"tiny_png" operation="crop" width=32 height=32 format="png" if-image-name-on="#{name_list}"
|
|
22
|
+
"bad" operation="crop" width=0 height=0 if-image-name-on="#{name_list}"
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
store_s3 "input"
|
|
25
|
-
store_s3 "small"
|
|
26
|
-
store_s3 "tiny_png"
|
|
25
|
+
store_s3 "input" bucket="@AWS_S3_TEST_BUCKET@" path="structured" public=true
|
|
26
|
+
store_s3 "small" bucket="@AWS_S3_TEST_BUCKET@" path="structured-name" public=true if-image-name-on="#{name_list}"
|
|
27
|
+
store_s3 "tiny_png" bucket="@AWS_S3_TEST_BUCKET@" path="structured-name" public=true if-image-name-on="#{name_list}"
|
|
27
28
|
|
|
28
29
|
output_store_url {
|
|
29
30
|
"input"
|
|
30
|
-
"small"
|
|
31
|
-
"tiny_png"
|
|
31
|
+
"small" if-image-name-on="#{name_list}"
|
|
32
|
+
"tiny_png" if-image-name-on="#{name_list}"
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
put "thumbnail" ":name_list" {
|
|
36
37
|
thumbnail "input" {
|
|
37
|
-
"small"
|
|
38
|
-
"tiny_png"
|
|
38
|
+
"small" operation="crop" width=128 height=128 format="jpeg" if-image-name-on="#{name_list}"
|
|
39
|
+
"tiny_png" operation="crop" width=32 height=32 format="png" if-image-name-on="#{name_list}"
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
store_s3 "input"
|
|
42
|
-
store_s3 "small"
|
|
43
|
-
store_s3 "tiny_png"
|
|
42
|
+
store_s3 "input" bucket="@AWS_S3_TEST_BUCKET@" path="hash" public=true
|
|
43
|
+
store_s3 "small" bucket="@AWS_S3_TEST_BUCKET@" path="hash-name" public=true if-image-name-on="#{name_list}"
|
|
44
|
+
store_s3 "tiny_png" bucket="@AWS_S3_TEST_BUCKET@" path="hash-name" public=true if-image-name-on="#{name_list}"
|
|
44
45
|
|
|
45
46
|
output_store_url {
|
|
46
47
|
"input"
|
|
47
|
-
"small"
|
|
48
|
-
"tiny_png"
|
|
49
|
-
"bad"
|
|
48
|
+
"small" if-image-name-on="#{name_list}"
|
|
49
|
+
"tiny_png" if-image-name-on="#{name_list}"
|
|
50
|
+
"bad" if-image-name-on="#{name_list}"
|
|
50
51
|
}
|
|
51
52
|
}
|
|
53
|
+
|
|
54
|
+
# Forward compatible getting of thumbnails
|
|
55
|
+
get "thumbnail" ":hash/[0-f]{16}/" ":type/.*-square.jpg/" {
|
|
56
|
+
source_s3 "original" bucket="@AWS_S3_TEST_BUCKET@" path="flexi-original"
|
|
57
|
+
thumbnail "original" "thumbnail" operation="crop" width="50" height="50"
|
|
58
|
+
output_image "thumbnail" cache-control="public, max-age=31557600, s-maxage=0"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get "thumbnail" ":hash/[0-f]{16}/" ":type/.*-normal.jpg/" {
|
|
62
|
+
source_s3 "original" bucket="@AWS_S3_TEST_BUCKET@" path="flexi-original"
|
|
63
|
+
thumbnail "original" "thumbnail" operation="fit" width="100" height="2000"
|
|
64
|
+
output_image "thumbnail" cache-control="public, max-age=31557600, s-maxage=0"
|
|
65
|
+
}
|
|
52
66
|
"""
|
|
53
67
|
|
|
54
|
-
@compatibility
|
|
68
|
+
@compatibility
|
|
55
69
|
Scenario: Putting original and its thumbnails to S3 bucket
|
|
56
70
|
Given there is no 4006450256177f4a.jpg file in S3 bucket
|
|
57
71
|
And there is no 4006450256177f4a/small.jpg file in S3 bucket
|
|
@@ -127,3 +141,14 @@ Feature: Image list based thumbnailing and S3 storage
|
|
|
127
141
|
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/test/图像/4006450256177f4a/测试.jpg will contain JPEG image of size 509x719
|
|
128
142
|
And http://@AWS_S3_TEST_BUCKET@.s3.amazonaws.com/test/图像/4006450256177f4a/测试-small.jpg will contain JPEG image of size 128x128
|
|
129
143
|
|
|
144
|
+
@compatibility @forward @test
|
|
145
|
+
Scenario: Getting thumbanils requested with compatibility API from flexi bucket
|
|
146
|
+
Given test.jpg file content is stored in S3 under 1234567890123456.jpg
|
|
147
|
+
When I do GET request http://localhost:3000/thumbnail/1234567890123456/foobar-blah-square.jpg
|
|
148
|
+
Then response status will be 200
|
|
149
|
+
And response content type will be image/jpeg
|
|
150
|
+
Then response body will contain JPEG image of size 50x50
|
|
151
|
+
When I do GET request http://localhost:3000/thumbnail/1234567890123456/foobar-blah-normal.jpg
|
|
152
|
+
Then response status will be 200
|
|
153
|
+
And response content type will be image/jpeg
|
|
154
|
+
Then response body will contain JPEG image of size 100x141
|
|
@@ -9,28 +9,28 @@ Feature: Image list based thumbnailing and S3 storage
|
|
|
9
9
|
"""
|
|
10
10
|
s3 key="@AWS_ACCESS_KEY_ID@" secret="@AWS_SECRET_ACCESS_KEY@" ssl=false
|
|
11
11
|
|
|
12
|
-
path "structured-name"
|
|
13
|
-
path "missing"
|
|
14
|
-
path "zero"
|
|
12
|
+
path "structured-name" "#{dirname}/#{input_digest}/#{basename}-#{image_name}.#{image_mime_extension}"
|
|
13
|
+
path "missing" "blah"
|
|
14
|
+
path "zero" "zero"
|
|
15
15
|
|
|
16
16
|
put "multipart" ":name_list" {
|
|
17
17
|
thumbnail "input" {
|
|
18
|
-
"small"
|
|
19
|
-
"bad"
|
|
20
|
-
"bad_dim"
|
|
21
|
-
"superlarge"
|
|
22
|
-
"large_png"
|
|
23
|
-
"bad_opts"
|
|
18
|
+
"small" operation="crop" width=128 height=128 if-image-name-on="#{name_list}"
|
|
19
|
+
"bad" operation="crop" width=0 height=0 if-image-name-on="#{name_list}"
|
|
20
|
+
"bad_dim" operation="crop" width="128x" height=128 if-image-name-on="#{name_list}"
|
|
21
|
+
"superlarge" operation="crop" width=16000 height=16000 if-image-name-on="#{name_list}"
|
|
22
|
+
"large_png" operation="crop" width=7000 height=7000 format="png" if-image-name-on="#{name_list}"
|
|
23
|
+
"bad_opts" operation="crop" width=128 height=128 options="foo=bar" if-image-name-on="#{name_list}"
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
put "singlepart" ":name_list" {
|
|
28
|
-
thumbnail "input"
|
|
29
|
-
thumbnail "input"
|
|
30
|
-
thumbnail "input"
|
|
31
|
-
thumbnail "input"
|
|
32
|
-
thumbnail "input"
|
|
33
|
-
thumbnail "input"
|
|
28
|
+
thumbnail "input" "small" operation="crop" width=128 height=128 if-image-name-on="#{name_list}"
|
|
29
|
+
thumbnail "input" "bad" operation="crop" width=0 height=0 if-image-name-on="#{name_list}"
|
|
30
|
+
thumbnail "input" "bad_dim" operation="crop" width="128x" height=128 if-image-name-on="#{name_list}"
|
|
31
|
+
thumbnail "input" "superlarge" operation="crop" width=16000 height=16000 if-image-name-on="#{name_list}"
|
|
32
|
+
thumbnail "input" "large_png" operation="crop" width=7000 height=7000 format="png" if-image-name-on="#{name_list}"
|
|
33
|
+
thumbnail "input" "bad_opts" operation="crop" width=128 height=128 options="foo=bar" if-image-name-on="#{name_list}"
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
get "s3" {
|
|
@@ -250,4 +250,3 @@ Feature: Image list based thumbnailing and S3 storage
|
|
|
250
250
|
"""
|
|
251
251
|
cannot generate path 'no_image_meta' from template '#{image_mime_extension}': image 'input' does not have data for variable 'image_mime_extension'
|
|
252
252
|
"""
|
|
253
|
-
|
data/features/flexi.feature
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Feature: Flexible API with two storage options and Facebook like thumbnailing URL format
|
|
2
|
-
Features two storage
|
|
2
|
+
Features two storage approaches: with JPEG conversion and limiting in size - for user provided content - and storing as is.
|
|
3
3
|
POST requests will end up with server side generated storage key based on input data digest.
|
|
4
|
-
PUT
|
|
5
|
-
Thumbnail GET API is
|
|
4
|
+
PUT requests can be used to store image under provided storage key.
|
|
5
|
+
Thumbnail GET API is similar to described in https://developers.facebook.com/docs/reference/api/using-pictures/#sizes.
|
|
6
6
|
Stored object extension and content type is determined from image data.
|
|
7
7
|
|
|
8
8
|
Background:
|
|
@@ -256,5 +256,4 @@ Feature: Flexible API with two storage options and Facebook like thumbnailing UR
|
|
|
256
256
|
And I do GET request http://localhost:3000/pictures/test.png?height=321
|
|
257
257
|
Then response status will be 200
|
|
258
258
|
And response content type will be image/png
|
|
259
|
-
Then response body will contain PNG image of size 227x321
|
|
260
|
-
|
|
259
|
+
Then response body will contain PNG image of size 227x321
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
Feature: Request matching
|
|
2
|
+
Incoming requests needs to be matched in flexible way and appropriate data needs to be available in form of variables used to parametrize processing.
|
|
3
|
+
|
|
4
|
+
Background:
|
|
5
|
+
Given httpthumbnailer server is running at http://localhost:3100/health_check
|
|
6
|
+
Given httpimagestore server is running at http://localhost:3000/health_check with the following configuration
|
|
7
|
+
"""
|
|
8
|
+
# URI segment matchers
|
|
9
|
+
get "string" {
|
|
10
|
+
output_text "path: '#{path}'"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get "any" "default" ":test1" ":test2?foo" ":test3?bar" ":test4?baz" {
|
|
14
|
+
output_text "test1: '#{test1}' test2: '#{test2}' test3: '#{test3}' test4: '#{test4}' path: '#{path}'"
|
|
15
|
+
}
|
|
16
|
+
get "any" ":test1" ":test2" {
|
|
17
|
+
output_text "test1: '#{test1}' test2: '#{test2}' path: '#{path}'"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get "regexp1" ":test1/a.c/" ":test2/.*/" {
|
|
21
|
+
output_text "test1: '#{test1}' test2: '#{test2}' path: '#{path}'"
|
|
22
|
+
}
|
|
23
|
+
get "regexp-404" ":test1/a.c.*/" ":test2/\\./" {
|
|
24
|
+
output_text "test1: '#{test1}' test2: '#{test2}' path: '#{path}'"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get "regexp" "named" "/(?<test1>..)-(?<test2>..)/" ":test3/.*/" {
|
|
28
|
+
output_text "test1: '#{test1}' test2: '#{test2}' test3: '#{test3}' path: '#{path}'"
|
|
29
|
+
}
|
|
30
|
+
get "regexp" "named" "nocapture" "/..-../" {
|
|
31
|
+
output_text "path: '#{path}'"
|
|
32
|
+
}
|
|
33
|
+
get "regexp" "named" "bad1" "/(?<test1>..)-(?<test1>..)/" ":test3/.*/" {
|
|
34
|
+
output_text "test1: '#{test1}' test2: '#{test2}' test3: '#{test3}' path: '#{path}'"
|
|
35
|
+
}
|
|
36
|
+
get "regexp" "named" "bad2" "/(?<test1>..)-(?<test1>..)/" ":test3/.*/" {
|
|
37
|
+
output_text "test1: '#{test1}' test3: '#{test3}' path: '#{path}'"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Query string matchers
|
|
41
|
+
get "query" "key-value" "&hello=world" {
|
|
42
|
+
output_text "query key-value matched path: '#{path}'"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get "query" "key" "default" "&:hello?abc" {
|
|
46
|
+
output_text "key: '#{hello}' path: '#{path}'"
|
|
47
|
+
}
|
|
48
|
+
get "query" "key" "&:hello" {
|
|
49
|
+
output_text "key: '#{hello}' path: '#{path}'"
|
|
50
|
+
}
|
|
51
|
+
get "query" "options" {
|
|
52
|
+
output_text "query_string_options: '#{query_string_options}' path: '#{path}'"
|
|
53
|
+
}
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
@request-matching @string
|
|
57
|
+
Scenario: Matching URI segment with strings
|
|
58
|
+
When I do GET request http://localhost:3000/string/hello/world
|
|
59
|
+
Then response status will be 200
|
|
60
|
+
And response content type will be text/plain
|
|
61
|
+
And response body will be CRLF ended lines
|
|
62
|
+
"""
|
|
63
|
+
path: 'hello/world'
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
@request-matching @capture-any
|
|
67
|
+
Scenario: Capturing any URI segment
|
|
68
|
+
When I do GET request http://localhost:3000/any/foo/bar/hello/world
|
|
69
|
+
Then response status will be 200
|
|
70
|
+
And response content type will be text/plain
|
|
71
|
+
And response body will be CRLF ended lines
|
|
72
|
+
"""
|
|
73
|
+
test1: 'foo' test2: 'bar' path: 'hello/world'
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
@request-matching @capture-any-default
|
|
77
|
+
Scenario: Capturing any URI segment with default value
|
|
78
|
+
When I do GET request http://localhost:3000/any/default/foo/bar
|
|
79
|
+
Then response status will be 200
|
|
80
|
+
And response content type will be text/plain
|
|
81
|
+
And response body will be CRLF ended lines
|
|
82
|
+
"""
|
|
83
|
+
test1: 'foo' test2: 'bar' test3: 'bar' test4: 'baz' path: ''
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
@request-matching @capture-regexp
|
|
87
|
+
Scenario: Capturing URI segment with regexp match
|
|
88
|
+
When I do GET request http://localhost:3000/regexp1/abc/foobar/hello/world
|
|
89
|
+
Then response status will be 200
|
|
90
|
+
And response content type will be text/plain
|
|
91
|
+
And response body will be CRLF ended lines
|
|
92
|
+
"""
|
|
93
|
+
test1: 'abc' test2: 'foobar/hello/world' path: ''
|
|
94
|
+
"""
|
|
95
|
+
When I do GET request http://localhost:3000/regexp2/abc/foobar/hello/world
|
|
96
|
+
Then response status will be 404
|
|
97
|
+
|
|
98
|
+
@request-matching @capture-named-regexp
|
|
99
|
+
Scenario: Capturing URI segment with named regexp match
|
|
100
|
+
When I do GET request http://localhost:3000/regexp/named/ab-12/hello/world
|
|
101
|
+
Then response status will be 200
|
|
102
|
+
And response content type will be text/plain
|
|
103
|
+
And response body will be CRLF ended lines
|
|
104
|
+
"""
|
|
105
|
+
test1: 'ab' test2: '12' test3: 'hello/world' path: ''
|
|
106
|
+
"""
|
|
107
|
+
When I do GET request http://localhost:3000/regexp/named/nocapture/ab-12/hello/world
|
|
108
|
+
Then response status will be 200
|
|
109
|
+
And response content type will be text/plain
|
|
110
|
+
And response body will be CRLF ended lines
|
|
111
|
+
"""
|
|
112
|
+
path: 'hello/world'
|
|
113
|
+
"""
|
|
114
|
+
When I do GET request http://localhost:3000/regexp/named/ab-12
|
|
115
|
+
Then response status will be 404
|
|
116
|
+
When I do GET request http://localhost:3000/regexp/named/ab-123/hello/world
|
|
117
|
+
Then response status will be 404
|
|
118
|
+
When I do GET request http://localhost:3000/regexp/named/bad1/ab-12/hello/world
|
|
119
|
+
Then response status will be 500
|
|
120
|
+
When I do GET request http://localhost:3000/regexp/named/bad2/ab-12/hello/world
|
|
121
|
+
Then response status will be 500
|
|
122
|
+
And response body will be CRLF ended lines
|
|
123
|
+
"""
|
|
124
|
+
matched more arguments than named (3 for 2)
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
@request-matching @query-key-value
|
|
128
|
+
Scenario: Capturing URI by presence of given key-value query string pair
|
|
129
|
+
When I do GET request http://localhost:3000/query/key-value/hello/world?hello=world
|
|
130
|
+
Then response status will be 200
|
|
131
|
+
And response content type will be text/plain
|
|
132
|
+
And response body will be CRLF ended lines
|
|
133
|
+
"""
|
|
134
|
+
query key-value matched path: 'hello/world'
|
|
135
|
+
"""
|
|
136
|
+
When I do GET request http://localhost:3000/query/key-value/hello/world?foo=bar&hello=world&bar=baz
|
|
137
|
+
Then response status will be 200
|
|
138
|
+
And response content type will be text/plain
|
|
139
|
+
And response body will be CRLF ended lines
|
|
140
|
+
"""
|
|
141
|
+
query key-value matched path: 'hello/world'
|
|
142
|
+
"""
|
|
143
|
+
When I do GET request http://localhost:3000/query/key-value/hello/world
|
|
144
|
+
Then response status will be 404
|
|
145
|
+
When I do GET request http://localhost:3000/query/key-value/hello/world?hello=Xorld
|
|
146
|
+
Then response status will be 404
|
|
147
|
+
When I do GET request http://localhost:3000/query/key-value/hello/world?heXlo=world
|
|
148
|
+
Then response status will be 404
|
|
149
|
+
|
|
150
|
+
@request-matching @query-key
|
|
151
|
+
Scenario: Capturing URI by query string key presence
|
|
152
|
+
When I do GET request http://localhost:3000/query/key/hello/world?hello=world
|
|
153
|
+
Then response status will be 200
|
|
154
|
+
And response content type will be text/plain
|
|
155
|
+
And response body will be CRLF ended lines
|
|
156
|
+
"""
|
|
157
|
+
key: 'world' path: 'hello/world'
|
|
158
|
+
"""
|
|
159
|
+
When I do GET request http://localhost:3000/query/key/hello/world?foo=bar&hello=foobar&bar=baz
|
|
160
|
+
Then response status will be 200
|
|
161
|
+
And response content type will be text/plain
|
|
162
|
+
And response body will be CRLF ended lines
|
|
163
|
+
"""
|
|
164
|
+
key: 'foobar' path: 'hello/world'
|
|
165
|
+
"""
|
|
166
|
+
When I do GET request http://localhost:3000/query/key/hello/world
|
|
167
|
+
Then response status will be 404
|
|
168
|
+
When I do GET request http://localhost:3000/query/key/hello/world?heXlo=world
|
|
169
|
+
Then response status will be 404
|
|
170
|
+
|
|
171
|
+
@request-matching @query-key-default
|
|
172
|
+
Scenario: Capturing URI by query string key presence
|
|
173
|
+
When I do GET request http://localhost:3000/query/key/default/hello/world?hello=world
|
|
174
|
+
Then response status will be 200
|
|
175
|
+
And response content type will be text/plain
|
|
176
|
+
And response body will be CRLF ended lines
|
|
177
|
+
"""
|
|
178
|
+
key: 'world' path: 'hello/world'
|
|
179
|
+
"""
|
|
180
|
+
When I do GET request http://localhost:3000/query/key/default/hello/world?foo=bar&hello=foobar&bar=baz
|
|
181
|
+
Then response status will be 200
|
|
182
|
+
And response content type will be text/plain
|
|
183
|
+
And response body will be CRLF ended lines
|
|
184
|
+
"""
|
|
185
|
+
key: 'foobar' path: 'hello/world'
|
|
186
|
+
"""
|
|
187
|
+
When I do GET request http://localhost:3000/query/key/default/hello/world
|
|
188
|
+
Then response status will be 200
|
|
189
|
+
And response content type will be text/plain
|
|
190
|
+
And response body will be CRLF ended lines
|
|
191
|
+
"""
|
|
192
|
+
key: 'abc' path: 'hello/world'
|
|
193
|
+
"""
|
|
194
|
+
When I do GET request http://localhost:3000/query/key/default/hello/world?heXlo=world
|
|
195
|
+
Then response status will be 200
|
|
196
|
+
And response content type will be text/plain
|
|
197
|
+
And response body will be CRLF ended lines
|
|
198
|
+
"""
|
|
199
|
+
key: 'abc' path: 'hello/world'
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
@request-matching @query-string-options
|
|
203
|
+
Scenario: URI query string key-value pairs should always be available as query_string_options variable
|
|
204
|
+
When I do GET request http://localhost:3000/query/options/hello/world?foo=hello&bar=world
|
|
205
|
+
Then response status will be 200
|
|
206
|
+
And response content type will be text/plain
|
|
207
|
+
And response body will be CRLF ended lines
|
|
208
|
+
"""
|
|
209
|
+
query_string_options: 'bar:world,foo:hello' path: 'hello/world'
|
|
210
|
+
"""
|
|
211
|
+
|
|
@@ -10,30 +10,24 @@ Feature: Store limited original image in S3 and thumbnail based on request
|
|
|
10
10
|
"""
|
|
11
11
|
s3 key="@AWS_ACCESS_KEY_ID@" secret="@AWS_SECRET_ACCESS_KEY@" ssl=false
|
|
12
12
|
|
|
13
|
-
path "original-hash"
|
|
14
|
-
path "path"
|
|
13
|
+
path "original-hash" "#{input_digest}.#{image_mime_extension}"
|
|
14
|
+
path "path" "#{path}"
|
|
15
15
|
|
|
16
16
|
put "original" {
|
|
17
17
|
thumbnail "input" "original" operation="limit" width=100 height=100 format="jpeg" quality=95
|
|
18
|
-
|
|
19
18
|
store_s3 "original" bucket="@AWS_S3_TEST_BUCKET@" path="original-hash" cache-root="/tmp"
|
|
20
|
-
|
|
21
19
|
output_store_path "original"
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
get "thumbnail" "v1" ":path" ":operation" ":width" ":height" ":options?" {
|
|
25
23
|
source_s3 "original" bucket="@AWS_S3_TEST_BUCKET@" path="path"
|
|
26
|
-
|
|
27
24
|
thumbnail "original" "thumbnail" operation="#{operation}" width="#{width}" height="#{height}" options="#{options}" quality=84 format="png"
|
|
28
|
-
|
|
29
25
|
output_image "thumbnail" cache-control="public, max-age=31557600, s-maxage=0"
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
get "thumbnail" "v2" ":operation" ":width" ":height" {
|
|
33
29
|
source_s3 "original" bucket="@AWS_S3_TEST_BUCKET@" path="path" cache-root="/tmp"
|
|
34
|
-
|
|
35
30
|
thumbnail "original" "thumbnail" operation="#{operation}" width="#{width}" height="#{height}" options="#{query_string_options}" quality=84 format="png"
|
|
36
|
-
|
|
37
31
|
output_image "thumbnail" cache-control="public, max-age=31557600, s-maxage=0"
|
|
38
32
|
}
|
|
39
33
|
"""
|
|
@@ -85,5 +79,4 @@ Feature: Store limited original image in S3 and thumbnail based on request
|
|
|
85
79
|
Then response status will be 200
|
|
86
80
|
And response content type will be image/png
|
|
87
81
|
Then response body will contain PNG image of size 50x50
|
|
88
|
-
And that image pixel at 2x2 should be of color green
|
|
89
|
-
|
|
82
|
+
And that image pixel at 2x2 should be of color green
|