httpimagestore 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +7 -7
  3. data/Gemfile.lock +20 -20
  4. data/README.md +165 -37
  5. data/Rakefile +7 -2
  6. data/VERSION +1 -1
  7. data/bin/httpimagestore +74 -41
  8. data/lib/httpimagestore/configuration/file.rb +20 -11
  9. data/lib/httpimagestore/configuration/handler.rb +96 -257
  10. data/lib/httpimagestore/configuration/handler/source_store_base.rb +37 -0
  11. data/lib/httpimagestore/configuration/handler/statement.rb +114 -0
  12. data/lib/httpimagestore/configuration/identify.rb +17 -9
  13. data/lib/httpimagestore/configuration/output.rb +33 -61
  14. data/lib/httpimagestore/configuration/path.rb +2 -2
  15. data/lib/httpimagestore/configuration/request_state.rb +131 -0
  16. data/lib/httpimagestore/configuration/s3.rb +41 -29
  17. data/lib/httpimagestore/configuration/thumbnailer.rb +189 -96
  18. data/lib/httpimagestore/configuration/validate_hmac.rb +170 -0
  19. data/lib/httpimagestore/error_reporter.rb +6 -1
  20. data/lib/httpimagestore/ruby_string_template.rb +10 -19
  21. metadata +40 -102
  22. data/.rspec +0 -1
  23. data/features/cache-control.feature +0 -41
  24. data/features/compatibility.feature +0 -165
  25. data/features/data-uri.feature +0 -55
  26. data/features/encoding.feature +0 -103
  27. data/features/error-reporting.feature +0 -281
  28. data/features/flexi.feature +0 -259
  29. data/features/health-check.feature +0 -29
  30. data/features/request-matching.feature +0 -211
  31. data/features/rewrite.feature +0 -122
  32. data/features/s3-store-and-thumbnail.feature +0 -82
  33. data/features/source-failover.feature +0 -71
  34. data/features/step_definitions/httpimagestore_steps.rb +0 -203
  35. data/features/storage.feature +0 -198
  36. data/features/support/env.rb +0 -116
  37. data/features/support/test-large.jpg +0 -0
  38. data/features/support/test.empty +0 -0
  39. data/features/support/test.jpg +0 -0
  40. data/features/support/test.png +0 -0
  41. data/features/support/test.txt +0 -1
  42. data/features/support/tiny.png +0 -0
  43. data/features/xid-forwarding.feature +0 -49
  44. data/httpimagestore.gemspec +0 -145
  45. data/load_test/load_test.1k.23a022f6e.m1.small-comp.csv +0 -3
  46. data/load_test/load_test.1k.ec9bde794.m1.small.csv +0 -4
  47. data/load_test/load_test.jmx +0 -317
  48. data/load_test/thumbnail_specs.csv +0 -11
  49. data/load_test/thumbnail_specs_v2.csv +0 -10
  50. data/spec/configuration_file_spec.rb +0 -333
  51. data/spec/configuration_handler_spec.rb +0 -255
  52. data/spec/configuration_identify_spec.rb +0 -67
  53. data/spec/configuration_output_spec.rb +0 -821
  54. data/spec/configuration_path_spec.rb +0 -138
  55. data/spec/configuration_s3_spec.rb +0 -911
  56. data/spec/configuration_source_failover_spec.rb +0 -101
  57. data/spec/configuration_spec.rb +0 -90
  58. data/spec/configuration_thumbnailer_spec.rb +0 -483
  59. data/spec/ruby_string_template_spec.rb +0 -61
  60. data/spec/spec_helper.rb +0 -89
  61. data/spec/support/compute.jpg +0 -0
  62. data/spec/support/cuba_response_env.rb +0 -40
  63. data/spec/support/full.cfg +0 -183
  64. data/spec/support/utf_string.txt +0 -1
@@ -0,0 +1,170 @@
1
+ require 'httpimagestore/configuration/handler/statement'
2
+ require 'securerandom'
3
+
4
+ module Configuration
5
+ class NoSecretKeySpecifiedError < ConfigurationError
6
+ def initialize
7
+ super 'no secret key given for validate_hmac (like secret="0f0f0...")'
8
+ end
9
+ end
10
+
11
+ class UnsupportedDigestError < ConfigurationError
12
+ def initialize(digest)
13
+ super "digest '#{digest}' is not supported"
14
+ end
15
+ end
16
+
17
+ class HMACAuthenticationFailedError < ArgumentError
18
+ def initialize(digest, msg)
19
+ super "HMAC URI authentication with digest '#{digest}' failed: #{msg}"
20
+ end
21
+ end
22
+
23
+ class HMACMismatchError < HMACAuthenticationFailedError
24
+ def initialize(expected_hmac, uri, digest)
25
+ super digest, "provided HMAC '#{expected_hmac}' for URI '#{uri}' is not valid"
26
+ end
27
+ end
28
+
29
+ class HMACMissingError < HMACAuthenticationFailedError
30
+ def initialize(hmac_qs_param_name, digest)
31
+ super digest, "HMAC query string parameter '#{hmac_qs_param_name}' not found"
32
+ end
33
+ end
34
+
35
+ class HMACMissingHeaderError < HMACAuthenticationFailedError
36
+ def initialize(digest, header_name)
37
+ super digest, "header '#{header_name}' not found in request body for HMAC verificaton"
38
+ end
39
+ end
40
+
41
+ class ValidateHMAC < HandlerStatement
42
+ include ConditionalInclusion
43
+
44
+ extend Stats
45
+ def_stats(
46
+ :total_hmac_validations,
47
+ :total_valid_hmac,
48
+ :total_invalid_hmac,
49
+ :total_lockpick_hmac
50
+ )
51
+
52
+ def self.new_with_common_options(configuration, node, hmac_qs_param_name, uri_source)
53
+ secret, digest, exclude, remove, lockpicks, remaining = *node.grab_attributes_with_remaining('secret', 'digest', 'exclude', 'remove', 'lockpicks')
54
+ conditions, remaining = *ConditionalInclusion.grab_conditions_with_remaining(remaining)
55
+ remaining.empty? or raise UnexpectedAttributesError.new(node, remaining)
56
+
57
+ obj = ValidateHMAC.new(hmac_qs_param_name, secret, lockpicks, digest, exclude, remove, uri_source)
58
+ obj.with_conditions(conditions)
59
+ obj
60
+ end
61
+
62
+ def initialize(hmac_qs_param_name, secret, lockpicks, digest, exclude, remove, uri_source)
63
+ @hmac_qs_param_name = hmac_qs_param_name
64
+ @secret = secret or raise NoSecretKeySpecifiedError
65
+ @digest = digest || 'sha1'
66
+
67
+ @exclude = (exclude || '').split(/ *, */)
68
+ @lockpicks = (lockpicks || '').split(/ *, */)
69
+ # always exclude hmac from hash computation
70
+ @exclude << @hmac_qs_param_name
71
+
72
+ # by default remove hmac for qs params but can be kept if remove=""
73
+ @remove = if remove
74
+ remove.split(/ *, */)
75
+ else
76
+ [@hmac_qs_param_name]
77
+ end
78
+
79
+ @uri_source = uri_source
80
+
81
+ # check if digest is valid
82
+ begin
83
+ OpenSSL::Digest.digest(@digest, 'blah')
84
+ rescue
85
+ raise UnsupportedDigestError.new(@digest)
86
+ end
87
+ end
88
+
89
+ attr_reader :digest
90
+
91
+ def realize(request_state)
92
+ expected_hmac = request_state.query_string[@hmac_qs_param_name] or raise HMACMissingError.new(@hmac_qs_param_name, @digest)
93
+
94
+ ValidateHMAC.stats.incr_total_hmac_validations
95
+
96
+ # we need to remove related query string params so we don't pass them as thumbnailer options
97
+ @remove.each do |rm|
98
+ log.debug "removing query string parameter '#{rm}' used for URI authentication"
99
+ request_state.query_string.delete(rm)
100
+ end
101
+
102
+ if lockpick = @lockpicks.detect{|lockpick| lockpick == expected_hmac}
103
+ # we try to get the URI if possible or else fail back to request_uri
104
+ # this is to help tracking where lockpicks are being used but still allow playing with APIs directly
105
+ # without need to set custom headers
106
+ lockpick_no = @lockpicks.find_index(lockpick) + 1
107
+ uri = @uri_source.call(self, request_state) rescue request_state.request_uri
108
+ uri = uri.gsub(/#{@exclude.last}=#{lockpick}/, "#{@exclude.last}=<lockpick #{lockpick_no} used>")
109
+
110
+ log.warn "valid lockpick provided! skipping URI HMAC validation for URI '#{uri}'"
111
+ ValidateHMAC.stats.incr_total_lockpick_hmac
112
+ return
113
+ end
114
+
115
+ uri = @uri_source.call(self, request_state) or fail "nil URI"
116
+ uri = @exclude.inject(uri) do |uri, ex|
117
+ uri.gsub(/(\?|&)#{ex}=.*?($|&)/, '\1')
118
+ end
119
+ uri.sub!(/(\?|&)$/, '')
120
+
121
+ digest = OpenSSL::Digest::Digest.new(@digest)
122
+
123
+ log.debug "validating URI '#{uri}' HMAC with digest '#{@digest}': expected HMAC '#{expected_hmac}'"
124
+ actual_hmac = OpenSSL::HMAC.hexdigest(digest, @secret, uri)
125
+
126
+ if actual_hmac != expected_hmac
127
+ sleep SecureRandom.random_number/10 # sleep some random time to make timing attack harder
128
+ log.warn "invalid HMAC with digest '#{@digest}' for URI '#{uri}'; expected HMAC '#{expected_hmac}'"
129
+ ValidateHMAC.stats.incr_total_invalid_hmac
130
+ raise HMACMismatchError.new(expected_hmac, uri, @digest)
131
+ else
132
+ ValidateHMAC.stats.incr_total_valid_hmac
133
+ end
134
+ end
135
+ end
136
+
137
+ class ValidateURIHMAC < ValidateHMAC
138
+ def self.match(node)
139
+ node.name == 'validate_uri_hmac'
140
+ end
141
+
142
+ def self.parse(configuration, node)
143
+ hmac_qs_param_name = node.grab_values('hmac').first
144
+ obj = self.new_with_common_options(configuration, node, hmac_qs_param_name, ->(obj, request_state){
145
+ request_state.request_uri
146
+ })
147
+ configuration.validators << obj
148
+ end
149
+ end
150
+
151
+ class ValidateHeaderHMAC < ValidateHMAC
152
+ def self.match(node)
153
+ node.name == 'validate_header_hmac'
154
+ end
155
+
156
+ def self.parse(configuration, node)
157
+ header_name, hmac_qs_param_name = *node.grab_values('header name', 'hmac')
158
+ header_name = header_name.upcase.gsub('_', '-')
159
+ obj = self.new_with_common_options(configuration, node, hmac_qs_param_name, ->(obj, request_state){
160
+ request_state.request_headers[header_name] or raise HMACMissingHeaderError.new(obj.digest, header_name)
161
+ })
162
+ configuration.validators << obj
163
+ end
164
+ end
165
+
166
+ Handler::register_node_parser ValidateURIHMAC
167
+ Handler::register_node_parser ValidateHeaderHMAC
168
+ StatsReporter << ValidateHMAC.stats
169
+ end
170
+
@@ -18,11 +18,16 @@ class ErrorReporter < Controller
18
18
 
19
19
  on error(
20
20
  Configuration::ZeroBodyLengthError,
21
- Configuration::NoSpecSelectedError
21
+ Configuration::NoSpecSelectedError,
22
+ Configuration::InvalidSpecError
22
23
  ) do |error|
23
24
  write_error 400, error
24
25
  end
25
26
 
27
+ on error(Configuration::HMACAuthenticationFailedError) do |error|
28
+ write_error 403, error
29
+ end
30
+
26
31
  on error Configuration::SourceFailoverAllFailedError do |error|
27
32
  if [Configuration::S3NoSuchKeyError, Configuration::NoSuchFileError].member? error.errors.first.class
28
33
  write_error 404, error
@@ -23,33 +23,20 @@ class RubyStringTemplate < String
23
23
  end
24
24
 
25
25
  def render(locals = {})
26
- template = self.to_s
27
- values = {}
28
-
29
- # use gsub with block instead!
30
- template.scan(/#\{[^\}]+\}/um).uniq.each do |placeholder|
26
+ self.gsub(/#\{[^\}]+\}/um) do |placeholder|
31
27
  name = placeholder.match(/#\{([^\}]*)\}/u).captures.first.to_sym
32
28
 
33
- value = nil
34
- @resolvers.find{|resolver| value = resolver.call(locals, name)} or fail NoValueForTemplatePlaceholderError.new(name, self)
35
- values[placeholder] = value.to_s
36
- end
37
-
38
- values.each_pair do |placeholder, value|
39
- template.gsub!(placeholder, value)
40
- end
41
-
42
- template
29
+ @resolvers.find do |resolver|
30
+ value = resolver.call(locals, name)
31
+ value and break value.to_s
32
+ end or fail NoValueForTemplatePlaceholderError.new(name, self)
33
+ end.to_s
43
34
  end
44
35
 
45
36
  def to_template
46
37
  self
47
38
  end
48
39
 
49
- #def inspect
50
- #super + "[#{@resolvers}]"
51
- #end
52
-
53
40
  def add_missing_resolver(&resolver)
54
41
  @resolvers << resolver
55
42
  end
@@ -59,6 +46,10 @@ class RubyStringTemplate < String
59
46
  new_template.add_missing_resolver(&resolver)
60
47
  new_template
61
48
  end
49
+
50
+ def inspect
51
+ "T<#{to_s}>"
52
+ end
62
53
  end
63
54
 
64
55
  class String
metadata CHANGED
@@ -1,52 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpimagestore
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
5
- prerelease:
4
+ version: 1.9.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jakub Pastuszek
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-08-28 00:00:00.000000000 Z
11
+ date: 2015-06-17 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: unicorn-cuba-base
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 1.2.2
19
+ version: '1.6'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
29
- version: 1.2.2
26
+ version: '1.6'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: httpthumbnailer-client
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
37
- version: 1.2.0
33
+ version: '1.3'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: 1.2.0
40
+ version: '1.3'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: aws-sdk
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
@@ -62,23 +55,26 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: mime-types
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
59
+ - - <
60
+ - !ruby/object:Gem::Version
61
+ version: '2.99'
67
62
  - - ~>
68
63
  - !ruby/object:Gem::Version
69
- version: '1.17'
64
+ version: '2.6'
70
65
  type: :runtime
71
66
  prerelease: false
72
67
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
68
  requirements:
69
+ - - <
70
+ - !ruby/object:Gem::Version
71
+ version: '2.99'
75
72
  - - ~>
76
73
  - !ruby/object:Gem::Version
77
- version: '1.17'
74
+ version: '2.6'
78
75
  - !ruby/object:Gem::Dependency
79
76
  name: sdl4r
80
77
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
78
  requirements:
83
79
  - - ~>
84
80
  - !ruby/object:Gem::Version
@@ -86,7 +82,6 @@ dependencies:
86
82
  type: :runtime
87
83
  prerelease: false
88
84
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
85
  requirements:
91
86
  - - ~>
92
87
  - !ruby/object:Gem::Version
@@ -94,7 +89,6 @@ dependencies:
94
89
  - !ruby/object:Gem::Dependency
95
90
  name: msgpack
96
91
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
92
  requirements:
99
93
  - - ~>
100
94
  - !ruby/object:Gem::Version
@@ -102,7 +96,6 @@ dependencies:
102
96
  type: :runtime
103
97
  prerelease: false
104
98
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
99
  requirements:
107
100
  - - ~>
108
101
  - !ruby/object:Gem::Version
@@ -110,7 +103,6 @@ dependencies:
110
103
  - !ruby/object:Gem::Dependency
111
104
  name: addressable
112
105
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
106
  requirements:
115
107
  - - ~>
116
108
  - !ruby/object:Gem::Version
@@ -118,7 +110,6 @@ dependencies:
118
110
  type: :runtime
119
111
  prerelease: false
120
112
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
113
  requirements:
123
114
  - - ~>
124
115
  - !ruby/object:Gem::Version
@@ -126,23 +117,20 @@ dependencies:
126
117
  - !ruby/object:Gem::Dependency
127
118
  name: faraday
128
119
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
120
  requirements:
131
- - - ! '>='
121
+ - - ~>
132
122
  - !ruby/object:Gem::Version
133
123
  version: '0.8'
134
124
  type: :development
135
125
  prerelease: false
136
126
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
127
  requirements:
139
- - - ! '>='
128
+ - - ~>
140
129
  - !ruby/object:Gem::Version
141
130
  version: '0.8'
142
131
  - !ruby/object:Gem::Dependency
143
132
  name: rspec
144
133
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
134
  requirements:
147
135
  - - ~>
148
136
  - !ruby/object:Gem::Version
@@ -150,7 +138,6 @@ dependencies:
150
138
  type: :development
151
139
  prerelease: false
152
140
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
141
  requirements:
155
142
  - - ~>
156
143
  - !ruby/object:Gem::Version
@@ -158,39 +145,40 @@ dependencies:
158
145
  - !ruby/object:Gem::Dependency
159
146
  name: cucumber
160
147
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
148
  requirements:
163
- - - ! '>='
149
+ - - ~>
164
150
  - !ruby/object:Gem::Version
165
- version: '0'
151
+ version: '1.3'
166
152
  type: :development
167
153
  prerelease: false
168
154
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
155
  requirements:
171
- - - ! '>='
156
+ - - ~>
172
157
  - !ruby/object:Gem::Version
173
- version: '0'
158
+ version: '1.3'
174
159
  - !ruby/object:Gem::Dependency
175
160
  name: jeweler
176
161
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
162
  requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: 1.8.8
179
166
  - - ~>
180
167
  - !ruby/object:Gem::Version
181
- version: 1.8.4
168
+ version: '1.8'
182
169
  type: :development
183
170
  prerelease: false
184
171
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
172
  requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: 1.8.8
187
176
  - - ~>
188
177
  - !ruby/object:Gem::Version
189
- version: 1.8.4
178
+ version: '1.8'
190
179
  - !ruby/object:Gem::Dependency
191
180
  name: rdoc
192
181
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
182
  requirements:
195
183
  - - ~>
196
184
  - !ruby/object:Gem::Version
@@ -198,7 +186,6 @@ dependencies:
198
186
  type: :development
199
187
  prerelease: false
200
188
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
189
  requirements:
203
190
  - - ~>
204
191
  - !ruby/object:Gem::Version
@@ -206,7 +193,6 @@ dependencies:
206
193
  - !ruby/object:Gem::Dependency
207
194
  name: daemon
208
195
  requirement: !ruby/object:Gem::Requirement
209
- none: false
210
196
  requirements:
211
197
  - - ~>
212
198
  - !ruby/object:Gem::Version
@@ -214,7 +200,6 @@ dependencies:
214
200
  type: :development
215
201
  prerelease: false
216
202
  version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
203
  requirements:
219
204
  - - ~>
220
205
  - !ruby/object:Gem::Version
@@ -222,7 +207,6 @@ dependencies:
222
207
  - !ruby/object:Gem::Dependency
223
208
  name: prawn
224
209
  requirement: !ruby/object:Gem::Requirement
225
- none: false
226
210
  requirements:
227
211
  - - '='
228
212
  - !ruby/object:Gem::Version
@@ -230,7 +214,6 @@ dependencies:
230
214
  type: :development
231
215
  prerelease: false
232
216
  version_requirements: !ruby/object:Gem::Requirement
233
- none: false
234
217
  requirements:
235
218
  - - '='
236
219
  - !ruby/object:Gem::Version
@@ -238,21 +221,19 @@ dependencies:
238
221
  - !ruby/object:Gem::Dependency
239
222
  name: httpthumbnailer
240
223
  requirement: !ruby/object:Gem::Requirement
241
- none: false
242
224
  requirements:
243
225
  - - ~>
244
226
  - !ruby/object:Gem::Version
245
- version: 1.2.0
227
+ version: '1.3'
246
228
  type: :development
247
229
  prerelease: false
248
230
  version_requirements: !ruby/object:Gem::Requirement
249
- none: false
250
231
  requirements:
251
232
  - - ~>
252
233
  - !ruby/object:Gem::Version
253
- version: 1.2.0
254
- description: Thumbnails images using httpthumbnailer and stored data on HTTP server
255
- (S3)
234
+ version: '1.3'
235
+ description: Configurable S3 or file system image storage and processing HTTP API
236
+ server. It is using HTTP Thumbnailer as image processing backend.
256
237
  email: jpastuszek@gmail.com
257
238
  executables:
258
239
  - httpimagestore
@@ -262,7 +243,6 @@ extra_rdoc_files:
262
243
  - README.md
263
244
  files:
264
245
  - .document
265
- - .rspec
266
246
  - Gemfile
267
247
  - Gemfile.lock
268
248
  - LICENSE.txt
@@ -270,86 +250,44 @@ files:
270
250
  - Rakefile
271
251
  - VERSION
272
252
  - bin/httpimagestore
273
- - features/cache-control.feature
274
- - features/compatibility.feature
275
- - features/data-uri.feature
276
- - features/encoding.feature
277
- - features/error-reporting.feature
278
- - features/flexi.feature
279
- - features/health-check.feature
280
- - features/request-matching.feature
281
- - features/rewrite.feature
282
- - features/s3-store-and-thumbnail.feature
283
- - features/source-failover.feature
284
- - features/step_definitions/httpimagestore_steps.rb
285
- - features/storage.feature
286
- - features/support/env.rb
287
- - features/support/test-large.jpg
288
- - features/support/test.empty
289
- - features/support/test.jpg
290
- - features/support/test.png
291
- - features/support/test.txt
292
- - features/support/tiny.png
293
- - features/xid-forwarding.feature
294
- - httpimagestore.gemspec
295
253
  - lib/httpimagestore/aws_sdk_regions_hack.rb
296
254
  - lib/httpimagestore/configuration.rb
297
255
  - lib/httpimagestore/configuration/file.rb
298
256
  - lib/httpimagestore/configuration/handler.rb
257
+ - lib/httpimagestore/configuration/handler/source_store_base.rb
258
+ - lib/httpimagestore/configuration/handler/statement.rb
299
259
  - lib/httpimagestore/configuration/identify.rb
300
260
  - lib/httpimagestore/configuration/output.rb
301
261
  - lib/httpimagestore/configuration/path.rb
262
+ - lib/httpimagestore/configuration/request_state.rb
302
263
  - lib/httpimagestore/configuration/s3.rb
303
264
  - lib/httpimagestore/configuration/source_failover.rb
304
265
  - lib/httpimagestore/configuration/thumbnailer.rb
266
+ - lib/httpimagestore/configuration/validate_hmac.rb
305
267
  - lib/httpimagestore/error_reporter.rb
306
268
  - lib/httpimagestore/ruby_string_template.rb
307
- - load_test/load_test.1k.23a022f6e.m1.small-comp.csv
308
- - load_test/load_test.1k.ec9bde794.m1.small.csv
309
- - load_test/load_test.jmx
310
- - load_test/thumbnail_specs.csv
311
- - load_test/thumbnail_specs_v2.csv
312
- - spec/configuration_file_spec.rb
313
- - spec/configuration_handler_spec.rb
314
- - spec/configuration_identify_spec.rb
315
- - spec/configuration_output_spec.rb
316
- - spec/configuration_path_spec.rb
317
- - spec/configuration_s3_spec.rb
318
- - spec/configuration_source_failover_spec.rb
319
- - spec/configuration_spec.rb
320
- - spec/configuration_thumbnailer_spec.rb
321
- - spec/ruby_string_template_spec.rb
322
- - spec/spec_helper.rb
323
- - spec/support/compute.jpg
324
- - spec/support/cuba_response_env.rb
325
- - spec/support/full.cfg
326
- - spec/support/utf_string.txt
327
269
  homepage: http://github.com/jpastuszek/httpimagestore
328
270
  licenses:
329
271
  - MIT
272
+ metadata: {}
330
273
  post_install_message:
331
274
  rdoc_options: []
332
275
  require_paths:
333
276
  - lib
334
277
  required_ruby_version: !ruby/object:Gem::Requirement
335
- none: false
336
278
  requirements:
337
279
  - - ! '>='
338
280
  - !ruby/object:Gem::Version
339
281
  version: '0'
340
- segments:
341
- - 0
342
- hash: 3314645469105412308
343
282
  required_rubygems_version: !ruby/object:Gem::Requirement
344
- none: false
345
283
  requirements:
346
284
  - - ! '>='
347
285
  - !ruby/object:Gem::Version
348
286
  version: '0'
349
287
  requirements: []
350
288
  rubyforge_project:
351
- rubygems_version: 1.8.23
289
+ rubygems_version: 2.4.7
352
290
  signing_key:
353
- specification_version: 3
354
- summary: HTTP based image storage and thumbnailer
291
+ specification_version: 4
292
+ summary: HTTP API server for image thumbnailing and storage
355
293
  test_files: []