httpimagestore 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile +7 -7
- data/Gemfile.lock +20 -20
- data/README.md +165 -37
- data/Rakefile +7 -2
- data/VERSION +1 -1
- data/bin/httpimagestore +74 -41
- data/lib/httpimagestore/configuration/file.rb +20 -11
- data/lib/httpimagestore/configuration/handler.rb +96 -257
- data/lib/httpimagestore/configuration/handler/source_store_base.rb +37 -0
- data/lib/httpimagestore/configuration/handler/statement.rb +114 -0
- data/lib/httpimagestore/configuration/identify.rb +17 -9
- data/lib/httpimagestore/configuration/output.rb +33 -61
- data/lib/httpimagestore/configuration/path.rb +2 -2
- data/lib/httpimagestore/configuration/request_state.rb +131 -0
- data/lib/httpimagestore/configuration/s3.rb +41 -29
- data/lib/httpimagestore/configuration/thumbnailer.rb +189 -96
- data/lib/httpimagestore/configuration/validate_hmac.rb +170 -0
- data/lib/httpimagestore/error_reporter.rb +6 -1
- data/lib/httpimagestore/ruby_string_template.rb +10 -19
- metadata +40 -102
- data/.rspec +0 -1
- data/features/cache-control.feature +0 -41
- data/features/compatibility.feature +0 -165
- data/features/data-uri.feature +0 -55
- data/features/encoding.feature +0 -103
- data/features/error-reporting.feature +0 -281
- data/features/flexi.feature +0 -259
- data/features/health-check.feature +0 -29
- data/features/request-matching.feature +0 -211
- data/features/rewrite.feature +0 -122
- data/features/s3-store-and-thumbnail.feature +0 -82
- data/features/source-failover.feature +0 -71
- data/features/step_definitions/httpimagestore_steps.rb +0 -203
- data/features/storage.feature +0 -198
- data/features/support/env.rb +0 -116
- data/features/support/test-large.jpg +0 -0
- data/features/support/test.empty +0 -0
- data/features/support/test.jpg +0 -0
- data/features/support/test.png +0 -0
- data/features/support/test.txt +0 -1
- data/features/support/tiny.png +0 -0
- data/features/xid-forwarding.feature +0 -49
- data/httpimagestore.gemspec +0 -145
- data/load_test/load_test.1k.23a022f6e.m1.small-comp.csv +0 -3
- data/load_test/load_test.1k.ec9bde794.m1.small.csv +0 -4
- data/load_test/load_test.jmx +0 -317
- data/load_test/thumbnail_specs.csv +0 -11
- data/load_test/thumbnail_specs_v2.csv +0 -10
- data/spec/configuration_file_spec.rb +0 -333
- data/spec/configuration_handler_spec.rb +0 -255
- data/spec/configuration_identify_spec.rb +0 -67
- data/spec/configuration_output_spec.rb +0 -821
- data/spec/configuration_path_spec.rb +0 -138
- data/spec/configuration_s3_spec.rb +0 -911
- data/spec/configuration_source_failover_spec.rb +0 -101
- data/spec/configuration_spec.rb +0 -90
- data/spec/configuration_thumbnailer_spec.rb +0 -483
- data/spec/ruby_string_template_spec.rb +0 -61
- data/spec/spec_helper.rb +0 -89
- data/spec/support/compute.jpg +0 -0
- data/spec/support/cuba_response_env.rb +0 -40
- data/spec/support/full.cfg +0 -183
- data/spec/support/utf_string.txt +0 -1
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'httpimagestore/configuration/handler/statement'
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
class SourceStoreBase < HandlerStatement
|
5
|
+
include ImageName
|
6
|
+
include ConditionalInclusion
|
7
|
+
include LocalConfiguration
|
8
|
+
include GlobalConfiguration
|
9
|
+
include PathSpec
|
10
|
+
|
11
|
+
def initialize(global, image_name, path_spec)
|
12
|
+
with_global_configuration(global)
|
13
|
+
with_image_name(image_name)
|
14
|
+
with_path_spec(path_spec)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def put_sourced_named_image(request_state)
|
20
|
+
rendered_path = path_template.render(request_state.with_locals(local_configuration))
|
21
|
+
|
22
|
+
image = yield @image_name, rendered_path
|
23
|
+
|
24
|
+
image.source_path = rendered_path
|
25
|
+
request_state.images[@image_name] = image
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_named_image_for_storage(request_state)
|
29
|
+
image = request_state.images[@image_name]
|
30
|
+
rendered_path = path_template.render(request_state.with_locals(local_configuration))
|
31
|
+
image.store_path = rendered_path
|
32
|
+
|
33
|
+
yield @image_name, image, rendered_path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'httpimagestore/configuration'
|
2
|
+
require 'httpimagestore/configuration/handler'
|
3
|
+
|
4
|
+
module Configuration
|
5
|
+
class HandlerStatement < Scope
|
6
|
+
# Base class for all statements that are within get/post/put/delete handler
|
7
|
+
#
|
8
|
+
module LocalConfiguration
|
9
|
+
attr_reader :local_configuration
|
10
|
+
def config_local(name, value)
|
11
|
+
@local_configuration ||= {}
|
12
|
+
@local_configuration[name] = value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ImageName
|
17
|
+
attr_reader :image_name
|
18
|
+
|
19
|
+
def with_image_name(image_name)
|
20
|
+
@image_name = image_name
|
21
|
+
config_local :imagename, @image_name # deprecated
|
22
|
+
config_local :image_name, @image_name
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module GlobalConfiguration
|
28
|
+
attr_reader :global
|
29
|
+
def with_global_configuration(global)
|
30
|
+
@global = global
|
31
|
+
end
|
32
|
+
|
33
|
+
def path_template(path_spec)
|
34
|
+
@global.paths[path_spec]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module PathSpec
|
39
|
+
attr_reader :path_spec
|
40
|
+
|
41
|
+
def with_path_spec(path_spec)
|
42
|
+
@path_spec = path_spec
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
# this is more specific than GlobalConfiguration
|
47
|
+
def path_template
|
48
|
+
@global.paths[@path_spec]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module ConditionalInclusion
|
53
|
+
class ImageNameOn
|
54
|
+
def initialize(template)
|
55
|
+
@template = template.to_template
|
56
|
+
end
|
57
|
+
|
58
|
+
def included?(request_state)
|
59
|
+
image_name = request_state[:image_name]
|
60
|
+
@template.render(request_state).split(',').include? image_name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class VariableMatches
|
65
|
+
def initialize(value)
|
66
|
+
param_name, template = value.split(':', 2)
|
67
|
+
@param_name = param_name.to_sym if param_name
|
68
|
+
@template = template.to_template if template
|
69
|
+
end
|
70
|
+
|
71
|
+
def included?(request_state)
|
72
|
+
return false if not @param_name
|
73
|
+
return !request_state[@param_name].empty? if not @template
|
74
|
+
@template.render(request_state) == request_state[@param_name]
|
75
|
+
rescue Configuration::VariableNotDefinedError
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.grab_conditions_with_remaining(attributes)
|
81
|
+
conditions = []
|
82
|
+
attributes = attributes.dup
|
83
|
+
|
84
|
+
if_image_name_on = attributes.delete('if-image-name-on')
|
85
|
+
conditions << ConditionalInclusion::ImageNameOn.new(if_image_name_on) if if_image_name_on
|
86
|
+
|
87
|
+
if_image_name_on = attributes.delete('if-variable-matches')
|
88
|
+
conditions << ConditionalInclusion::VariableMatches.new(if_image_name_on) if if_image_name_on
|
89
|
+
|
90
|
+
[conditions, attributes]
|
91
|
+
end
|
92
|
+
|
93
|
+
def with_conditions(conditions)
|
94
|
+
@conditions ||= []
|
95
|
+
@conditions.push(*conditions)
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
def included?(request_state)
|
100
|
+
return true if not @conditions or @conditions.empty?
|
101
|
+
# some conditions may use local_configuration vars
|
102
|
+
request_state = request_state.with_locals(local_configuration) if @local_configuration
|
103
|
+
@conditions.all? do |matcher|
|
104
|
+
matcher.included?(request_state)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def excluded?(request_state)
|
109
|
+
not included? request_state
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
@@ -5,6 +5,11 @@ require 'httpimagestore/configuration/handler'
|
|
5
5
|
module Configuration
|
6
6
|
class Identify < HandlerStatement
|
7
7
|
include ClassLogging
|
8
|
+
include ImageName
|
9
|
+
include LocalConfiguration
|
10
|
+
include GlobalConfiguration
|
11
|
+
include ConditionalInclusion
|
12
|
+
include PerfStats
|
8
13
|
|
9
14
|
extend Stats
|
10
15
|
def_stats(
|
@@ -18,18 +23,19 @@ module Configuration
|
|
18
23
|
|
19
24
|
def self.parse(configuration, node)
|
20
25
|
image_name = node.grab_values('image name').first
|
21
|
-
if_image_name_on = node.grab_attributes('if-image-name-on').first
|
22
26
|
|
23
|
-
|
27
|
+
conditions, remaining = *ConditionalInclusion.grab_conditions_with_remaining(node.attributes)
|
28
|
+
remaining.empty? or raise UnexpectedAttributesError.new(node, remaining)
|
24
29
|
|
25
|
-
|
26
|
-
|
30
|
+
iden = self.new(configuration.global, image_name)
|
31
|
+
iden.with_conditions(conditions)
|
27
32
|
|
28
|
-
|
29
|
-
|
33
|
+
configuration.processors << iden
|
34
|
+
end
|
30
35
|
|
31
|
-
def initialize(global, image_name
|
32
|
-
|
36
|
+
def initialize(global, image_name)
|
37
|
+
with_global_configuration(global)
|
38
|
+
with_image_name(image_name)
|
33
39
|
end
|
34
40
|
|
35
41
|
def realize(request_state)
|
@@ -41,7 +47,9 @@ module Configuration
|
|
41
47
|
Identify.stats.incr_total_identify_requests
|
42
48
|
Identify.stats.incr_total_identify_requests_bytes image.data.bytesize
|
43
49
|
|
44
|
-
id =
|
50
|
+
id = measure "identifying", @image_name do
|
51
|
+
client.with_headers(request_state.forward_headers).identify(image.data)
|
52
|
+
end
|
45
53
|
|
46
54
|
image.mime_type = id.mime_type if id.mime_type
|
47
55
|
image.width = id.width if id.width
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'httpimagestore/configuration/handler'
|
1
|
+
require 'httpimagestore/configuration/handler/statement'
|
2
2
|
require 'httpimagestore/ruby_string_template'
|
3
3
|
require 'addressable/uri'
|
4
4
|
require 'base64'
|
@@ -16,61 +16,18 @@ module Configuration
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
class OutputText
|
20
|
-
def self.match(node)
|
21
|
-
node.name == 'output_text'
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.parse(configuration, node)
|
25
|
-
configuration.output and raise StatementCollisionError.new(node, 'output')
|
26
|
-
text = node.grab_values('text').first
|
27
|
-
status, cache_control = *node.grab_attributes('status', 'cache-control')
|
28
|
-
configuration.output = OutputText.new(text, status || 200, cache_control)
|
29
|
-
end
|
30
|
-
|
31
|
-
def initialize(text, status, cache_control)
|
32
|
-
@text = RubyStringTemplate.new(text || fail("no text?!"))
|
33
|
-
@status = status || 200
|
34
|
-
@cache_control = cache_control
|
35
|
-
end
|
36
|
-
|
37
|
-
def realize(request_state)
|
38
|
-
# make sure variables are available in request context
|
39
|
-
status = @status
|
40
|
-
text = @text.render(request_state)
|
41
|
-
cache_control = @cache_control
|
42
|
-
request_state.output do
|
43
|
-
res['Cache-Control'] = cache_control if cache_control
|
44
|
-
write_plain status.to_i, text.to_s
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class OutputOK < OutputText
|
50
|
-
def self.match(node)
|
51
|
-
node.name == 'output_ok'
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.parse(configuration, node)
|
55
|
-
configuration.output and raise StatementCollisionError.new(node, 'output')
|
56
|
-
cache_control = node.grab_attributes('cache-control').first
|
57
|
-
configuration.output = OutputOK.new(cache_control)
|
58
|
-
end
|
59
|
-
|
60
|
-
def initialize(cache_control = nil)
|
61
|
-
super 'OK', 200, cache_control
|
62
|
-
end
|
63
|
-
end
|
64
|
-
Handler::register_node_parser OutputText
|
65
|
-
|
66
19
|
class OutputMultiBase
|
67
20
|
class OutputSpec < HandlerStatement
|
21
|
+
include GlobalConfiguration
|
68
22
|
include ImageName
|
69
23
|
include PathSpec
|
70
24
|
include ConditionalInclusion
|
25
|
+
include LocalConfiguration
|
71
26
|
|
72
|
-
def initialize(global, image_name, scheme, host, port, path_spec
|
73
|
-
|
27
|
+
def initialize(global, image_name, scheme, host, port, path_spec)
|
28
|
+
with_global_configuration(global)
|
29
|
+
with_image_name(image_name)
|
30
|
+
with_path_spec(path_spec)
|
74
31
|
@scheme = scheme && scheme.to_template
|
75
32
|
@host = host && host.to_template
|
76
33
|
@port = port && port.to_template
|
@@ -80,7 +37,7 @@ module Configuration
|
|
80
37
|
store_path = request_state.images[@image_name].store_path or raise StorePathNotSetForImage.new(@image_name)
|
81
38
|
return store_path unless @path_spec
|
82
39
|
|
83
|
-
path_template.render(request_state.with_locals(
|
40
|
+
path_template.render(request_state.with_locals(local_configuration, path: store_path))
|
84
41
|
end
|
85
42
|
|
86
43
|
def store_url(request_state)
|
@@ -96,7 +53,7 @@ module Configuration
|
|
96
53
|
request_locals[:host] = url.host if url.host
|
97
54
|
request_locals[:port] = url.port if url.port
|
98
55
|
|
99
|
-
request_state = request_state.with_locals(
|
56
|
+
request_state = request_state.with_locals(local_configuration, request_locals)
|
100
57
|
|
101
58
|
# optional rewrites
|
102
59
|
url.scheme = @scheme.render(request_state) if @scheme
|
@@ -112,9 +69,13 @@ module Configuration
|
|
112
69
|
nodes = node.values.empty? ? node.children : [node]
|
113
70
|
output_specs = nodes.map do |node|
|
114
71
|
image_name = node.grab_values('image name').first
|
115
|
-
scheme, host, port, path_spec,
|
116
|
-
|
117
|
-
|
72
|
+
scheme, host, port, path_spec, remaining = *node.grab_attributes_with_remaining('scheme', 'host', 'port', 'path')
|
73
|
+
conditions, remaining = *HandlerStatement::ConditionalInclusion.grab_conditions_with_remaining(remaining)
|
74
|
+
remaining.empty? or raise UnexpectedAttributesError.new(node, remaining)
|
75
|
+
|
76
|
+
out = OutputSpec.new(configuration.global, image_name, scheme, host, port, path_spec)
|
77
|
+
out.with_conditions(conditions)
|
78
|
+
out
|
118
79
|
end
|
119
80
|
|
120
81
|
configuration.output and raise StatementCollisionError.new(node, 'output')
|
@@ -125,10 +86,12 @@ module Configuration
|
|
125
86
|
@output_specs = output_specs
|
126
87
|
end
|
127
88
|
end
|
128
|
-
Handler::register_node_parser OutputOK
|
129
89
|
|
130
|
-
class OutputImage
|
90
|
+
class OutputImage < HandlerStatement
|
131
91
|
include ClassLogging
|
92
|
+
include ImageName
|
93
|
+
include LocalConfiguration
|
94
|
+
include PerfStats
|
132
95
|
|
133
96
|
def self.match(node)
|
134
97
|
node.name == 'output_image'
|
@@ -144,6 +107,7 @@ module Configuration
|
|
144
107
|
def initialize(name, cache_control)
|
145
108
|
@name = name
|
146
109
|
@cache_control = cache_control
|
110
|
+
with_image_name(name)
|
147
111
|
end
|
148
112
|
|
149
113
|
def realize(request_state)
|
@@ -157,15 +121,20 @@ module Configuration
|
|
157
121
|
end
|
158
122
|
|
159
123
|
cache_control = @cache_control
|
124
|
+
_context = self
|
160
125
|
request_state.output do
|
161
|
-
|
162
|
-
|
126
|
+
_context.measure "sending response image data", "mime type: #{mime_type} (image #{image.data.bytesize} bytes)" do
|
127
|
+
res['Cache-Control'] = cache_control if cache_control
|
128
|
+
write 200, mime_type, image.data
|
129
|
+
end
|
163
130
|
end
|
164
131
|
end
|
165
132
|
end
|
166
133
|
Handler::register_node_parser OutputImage
|
167
134
|
|
168
135
|
class OutputDataURIImage < OutputImage
|
136
|
+
include PerfStats
|
137
|
+
|
169
138
|
def self.match(node)
|
170
139
|
node.name == 'output_data_uri_image'
|
171
140
|
end
|
@@ -175,9 +144,12 @@ module Configuration
|
|
175
144
|
fail "image '#{@name}' needs to be identified first to be used in data URI output" unless image.mime_type
|
176
145
|
|
177
146
|
cache_control = @cache_control
|
147
|
+
_context = self
|
178
148
|
request_state.output do
|
179
|
-
|
180
|
-
|
149
|
+
_context.measure "sending response image data with data URI encoding", "mime type: #{image.mime_type} (image #{image.data.bytesize} bytes)" do
|
150
|
+
res['Cache-Control'] = cache_control if cache_control
|
151
|
+
write 200, 'text/uri-list', "data:#{image.mime_type};base64,#{Base64.strict_encode64(image.data)}"
|
152
|
+
end
|
181
153
|
end
|
182
154
|
end
|
183
155
|
end
|
@@ -15,7 +15,7 @@ module Configuration
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
class
|
18
|
+
class NoValueForPathTemplatePlaceholderError < PathRenderingError
|
19
19
|
def initialize(path_name, template, placeholder)
|
20
20
|
super path_name, template, "no value for '\#{#{placeholder}}'"
|
21
21
|
end
|
@@ -56,7 +56,7 @@ module Configuration
|
|
56
56
|
locals[name]
|
57
57
|
rescue ConfigurationError => error
|
58
58
|
raise PathRenderingError.new(path_name, template, error.message)
|
59
|
-
end or raise
|
59
|
+
end or raise NoValueForPathTemplatePlaceholderError.new(path_name, template, name)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
require 'digest/sha2'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module Configuration
|
6
|
+
class RequestState < Hash
|
7
|
+
include ClassLogging
|
8
|
+
|
9
|
+
class Images < Hash
|
10
|
+
def initialize(memory_limit)
|
11
|
+
@memory_limit = memory_limit
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(name, image)
|
16
|
+
if member?(name)
|
17
|
+
@memory_limit.return fetch(name).data.bytesize
|
18
|
+
end
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](name)
|
23
|
+
fetch(name){|image_name| raise ImageNotLoadedError.new(image_name)}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(body, matches, path, query_string, request_uri, request_headers, memory_limit, forward_headers)
|
28
|
+
super() do |request_state, name|
|
29
|
+
# note that request_state may be different object when useing with_locals that creates duplicate
|
30
|
+
request_state[name] = request_state.generate_meta_variable(name) or raise VariableNotDefinedError.new(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
# it is OK to overwrite path with a match
|
34
|
+
self[:path] = path
|
35
|
+
|
36
|
+
merge! matches
|
37
|
+
|
38
|
+
log.debug "processing request with body length: #{body.bytesize} bytes and variables: #{map{|k,v| "#{k}: '#{v}'"}.join(', ')}"
|
39
|
+
|
40
|
+
@body = body
|
41
|
+
@images = Images.new(memory_limit)
|
42
|
+
@query_string = query_string
|
43
|
+
@request_uri = request_uri
|
44
|
+
@request_headers = request_headers
|
45
|
+
@memory_limit = memory_limit
|
46
|
+
@output_callback = nil
|
47
|
+
|
48
|
+
@forward_headers = forward_headers
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_reader :body
|
52
|
+
attr_reader :images
|
53
|
+
attr_reader :memory_limit
|
54
|
+
attr_reader :query_string
|
55
|
+
attr_reader :request_uri
|
56
|
+
attr_reader :request_headers
|
57
|
+
attr_reader :forward_headers
|
58
|
+
|
59
|
+
def with_locals(*locals)
|
60
|
+
locals = locals.reduce{|a, b| a.merge(b)}
|
61
|
+
log.debug "using additional local variables: #{locals}"
|
62
|
+
self.dup.merge!(locals)
|
63
|
+
end
|
64
|
+
|
65
|
+
def output(&callback)
|
66
|
+
@output_callback = callback
|
67
|
+
end
|
68
|
+
|
69
|
+
def output_callback
|
70
|
+
@output_callback or fail 'no output callback'
|
71
|
+
end
|
72
|
+
|
73
|
+
def fetch_base_variable(name, base_name)
|
74
|
+
fetch(base_name, nil) or generate_meta_variable(base_name) or raise NoVariableToGenerateMetaVariableError.new(base_name, name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def generate_meta_variable(name)
|
78
|
+
val = case name
|
79
|
+
when :basename
|
80
|
+
path = Pathname.new(fetch_base_variable(name, :path))
|
81
|
+
path.basename(path.extname).to_s
|
82
|
+
when :dirname
|
83
|
+
Pathname.new(fetch_base_variable(name, :path)).dirname.to_s
|
84
|
+
when :extension
|
85
|
+
Pathname.new(fetch_base_variable(name, :path)).extname.delete('.')
|
86
|
+
when :digest # deprecated
|
87
|
+
@body.empty? and raise NoRequestBodyToGenerateMetaVariableError.new(name)
|
88
|
+
Digest::SHA2.new.update(@body).to_s[0,16]
|
89
|
+
when :input_digest
|
90
|
+
@body.empty? and raise NoRequestBodyToGenerateMetaVariableError.new(name)
|
91
|
+
Digest::SHA2.new.update(@body).to_s[0,16]
|
92
|
+
when :input_sha256
|
93
|
+
@body.empty? and raise NoRequestBodyToGenerateMetaVariableError.new(name)
|
94
|
+
Digest::SHA2.new.update(@body).to_s
|
95
|
+
when :input_image_width
|
96
|
+
@images['input'].width or raise NoImageDataForVariableError.new('input', name)
|
97
|
+
when :input_image_height
|
98
|
+
@images['input'].height or raise NoImageDataForVariableError.new('input', name)
|
99
|
+
when :input_image_mime_extension
|
100
|
+
@images['input'].mime_extension or raise NoImageDataForVariableError.new('input', name)
|
101
|
+
when :image_digest
|
102
|
+
Digest::SHA2.new.update(@images[fetch_base_variable(name, :image_name)].data).to_s[0,16]
|
103
|
+
when :image_sha256
|
104
|
+
Digest::SHA2.new.update(@images[fetch_base_variable(name, :image_name)].data).to_s
|
105
|
+
when :mimeextension # deprecated
|
106
|
+
image_name = fetch_base_variable(name, :image_name)
|
107
|
+
@images[image_name].mime_extension or raise NoImageDataForVariableError.new(image_name, name)
|
108
|
+
when :image_mime_extension
|
109
|
+
image_name = fetch_base_variable(name, :image_name)
|
110
|
+
@images[image_name].mime_extension or raise NoImageDataForVariableError.new(image_name, name)
|
111
|
+
when :image_width
|
112
|
+
image_name = fetch_base_variable(name, :image_name)
|
113
|
+
@images[image_name].width or raise NoImageDataForVariableError.new(image_name, name)
|
114
|
+
when :image_height
|
115
|
+
image_name = fetch_base_variable(name, :image_name)
|
116
|
+
@images[image_name].height or raise NoImageDataForVariableError.new(image_name, name)
|
117
|
+
when :uuid
|
118
|
+
SecureRandom.uuid
|
119
|
+
when :query_string_options
|
120
|
+
query_string.sort.map{|kv| kv.join(':')}.join(',')
|
121
|
+
end
|
122
|
+
if val
|
123
|
+
log.debug "generated meta variable '#{name}': #{val}"
|
124
|
+
else
|
125
|
+
log.debug "could not generated meta variable '#{name}'"
|
126
|
+
end
|
127
|
+
val
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|