blix-rest 0.9.3 → 0.11.2
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.
- checksums.yaml +4 -4
- data/README.md +485 -503
- data/lib/blix/rest/cache.rb +1 -29
- data/lib/blix/rest/controller.rb +95 -4
- data/lib/blix/rest/memory_cache.rb +30 -0
- data/lib/blix/rest/request_mapper.rb +36 -28
- data/lib/blix/rest/response.rb +10 -0
- data/lib/blix/rest/server.rb +61 -58
- data/lib/blix/rest/session.rb +8 -3
- data/lib/blix/rest/version.rb +1 -1
- data/lib/blix/rest.rb +7 -0
- data/lib/blix/utils/misc.rb +39 -0
- metadata +6 -10
- data/lib/blix/rest/cucumber/hooks.rb +0 -5
- data/lib/blix/rest/cucumber/request_steps.rb +0 -207
- data/lib/blix/rest/cucumber/resource_steps.rb +0 -28
- data/lib/blix/rest/cucumber/world.rb +0 -274
- data/lib/blix/rest/cucumber.rb +0 -8
data/lib/blix/rest/cache.rb
CHANGED
@@ -48,32 +48,4 @@ module Blix::Rest
|
|
48
48
|
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
class MemoryCache < Cache
|
53
|
-
|
54
|
-
def cache
|
55
|
-
@cache ||= {}
|
56
|
-
end
|
57
|
-
|
58
|
-
def get(key)
|
59
|
-
cache[key]
|
60
|
-
end
|
61
|
-
|
62
|
-
def set(key, data)
|
63
|
-
cache[key] = data
|
64
|
-
end
|
65
|
-
|
66
|
-
def clear
|
67
|
-
cache.clear
|
68
|
-
end
|
69
|
-
|
70
|
-
def key?(key)
|
71
|
-
cache.key?(key)
|
72
|
-
end
|
73
|
-
|
74
|
-
def delete(key)
|
75
|
-
cache.delete(key)
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|
51
|
+
end
|
data/lib/blix/rest/controller.rb
CHANGED
@@ -29,7 +29,8 @@ module Blix::Rest
|
|
29
29
|
:format,
|
30
30
|
:response,
|
31
31
|
:method,
|
32
|
-
:server
|
32
|
+
:server,
|
33
|
+
:response_options # can be set during a call.
|
33
34
|
)
|
34
35
|
|
35
36
|
class Controller
|
@@ -76,11 +77,16 @@ module Blix::Rest
|
|
76
77
|
end
|
77
78
|
|
78
79
|
def body
|
79
|
-
@_body ||=
|
80
|
-
|
80
|
+
@_body ||= begin
|
81
|
+
if env['rack.input']
|
82
|
+
env['rack.input'].read
|
83
|
+
else
|
84
|
+
''
|
85
|
+
end
|
86
|
+
end
|
81
87
|
end
|
82
88
|
|
83
|
-
#
|
89
|
+
# override the path method to return the internal path.
|
84
90
|
def path
|
85
91
|
p = CGI.unescape(req.path)
|
86
92
|
p = '/' + p if p[0, 1] != '/' # ensure a leading slash on path
|
@@ -241,6 +247,35 @@ module Blix::Rest
|
|
241
247
|
[login, password]
|
242
248
|
end
|
243
249
|
|
250
|
+
def throttle_basic_auth(realm=nil, options={})
|
251
|
+
login, password = get_basic_auth(realm)
|
252
|
+
# check that the waiting time has expired
|
253
|
+
info = self.class.basic_store.get_hash(login) || {}
|
254
|
+
fail_count = info['fail_count'].to_i
|
255
|
+
if fail_count > 3
|
256
|
+
now = Time.now
|
257
|
+
fail_time = info['fail_time']
|
258
|
+
delta = 60 # one minute
|
259
|
+
delta = 60*10 if fail_count > 10 # 10 minutes
|
260
|
+
delta = 60*60*24 if fail_count > 100 # one day
|
261
|
+
if (fail_time + delta) > now
|
262
|
+
raise Blix::Rest::AuthorizationError.new("try again after #{(fail_time + delta)}", realm)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
if yield(login,password)
|
266
|
+
# auth success - set error count to 0
|
267
|
+
info['fail_count'] = 0
|
268
|
+
self.class.basic_store.store_hash(login, info)
|
269
|
+
true
|
270
|
+
else
|
271
|
+
# auth failure - increment error count / set error time
|
272
|
+
info['fail_count'] = fail_count + 1
|
273
|
+
info['fail_time'] = Time.now
|
274
|
+
self.class.basic_store.store_hash(login, info)
|
275
|
+
raise Blix::Rest::AuthorizationError.new("invalid login or password", realm)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
244
279
|
# set the cors headers
|
245
280
|
def set_accept_cors(opts={})
|
246
281
|
origin = opts[:origin] || env['HTTP_ORIGIN'] || '*'
|
@@ -269,6 +304,11 @@ module Blix::Rest
|
|
269
304
|
@_response.status = value.to_i
|
270
305
|
end
|
271
306
|
|
307
|
+
def set_options(value)
|
308
|
+
@_context.response_options ||= {}
|
309
|
+
@_context.response_options.merge!(value)
|
310
|
+
end
|
311
|
+
|
272
312
|
def add_headers(headers)
|
273
313
|
@_response.headers.merge!(headers.map{|k,v| [k.to_s.downcase,v]}.to_h)
|
274
314
|
end
|
@@ -371,6 +411,57 @@ module Blix::Rest
|
|
371
411
|
value
|
372
412
|
end
|
373
413
|
|
414
|
+
# only allow so many exceptions in a given time.
|
415
|
+
# the delay applies to
|
416
|
+
# - 3x failure
|
417
|
+
# - 10x failure
|
418
|
+
# - 100x failure
|
419
|
+
|
420
|
+
# options:
|
421
|
+
# :prefix # the prefix to use in the cache
|
422
|
+
# :cache # a cache object ( server_cache )
|
423
|
+
# :times # array of delays in seconds to apply default: [60, 600, 86400]
|
424
|
+
#
|
425
|
+
def rate_limit(name, options = {})
|
426
|
+
# check that the waiting time has expired
|
427
|
+
cache = options[:cache] || server_cache()
|
428
|
+
prefix = options[:prefix] || 'rlimit'
|
429
|
+
key = "#{prefix}|#{name}"
|
430
|
+
info = cache.get(key) || {}
|
431
|
+
fail_count = info['fc'].to_i
|
432
|
+
times = options[:times] || []
|
433
|
+
if fail_count > 2
|
434
|
+
now = Time.now
|
435
|
+
fail_time = info['ft']
|
436
|
+
delta = times[0] || 60 # one minute
|
437
|
+
delta = times[1] || 60 * 10 if fail_count > 10 # 10 minutes
|
438
|
+
delta = times[2] || 60 * 60 * 24 if fail_count > 100 # one day
|
439
|
+
ltime = fail_time + delta
|
440
|
+
if ltime > now
|
441
|
+
raise RateError, ltime.to_s
|
442
|
+
end
|
443
|
+
end
|
444
|
+
exception = nil
|
445
|
+
result = begin
|
446
|
+
yield(key)
|
447
|
+
rescue Exception => e
|
448
|
+
exception = e
|
449
|
+
nil
|
450
|
+
end
|
451
|
+
if exception
|
452
|
+
# auth failure - increment error count / set error time
|
453
|
+
info['fc'] = fail_count + 1
|
454
|
+
info['ft'] = Time.now
|
455
|
+
cache.set(key, info)
|
456
|
+
raise exception
|
457
|
+
else
|
458
|
+
# auth success - set error count to 0
|
459
|
+
info['fc'] = 0
|
460
|
+
cache.set(key, info)
|
461
|
+
result
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
374
465
|
# manage session handling --------------------------------------------------
|
375
466
|
# setup the session and retrieve the session_id
|
376
467
|
# this id can be used to retrieve and data associated
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Blix::Rest
|
2
|
+
# implement cache as a simple ruby hash
|
3
|
+
class MemoryCache < Cache
|
4
|
+
|
5
|
+
def cache
|
6
|
+
@cache ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def get(key)
|
10
|
+
cache[key]
|
11
|
+
end
|
12
|
+
|
13
|
+
def set(key, data)
|
14
|
+
cache[key] = data
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear
|
18
|
+
cache.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
def key?(key)
|
22
|
+
cache.key?(key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete(key)
|
26
|
+
cache.delete(key)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -14,8 +14,9 @@ module Blix::Rest
|
|
14
14
|
PATH_SEP = '/'
|
15
15
|
STAR_PLACEHOLDER = '*'
|
16
16
|
|
17
|
-
# the
|
18
|
-
|
17
|
+
# the TableNode class is used to build a tree structure to
|
18
|
+
# represent the routes.
|
19
|
+
#
|
19
20
|
class TableNode
|
20
21
|
|
21
22
|
attr_accessor :blk
|
@@ -27,19 +28,7 @@ module Blix::Rest
|
|
27
28
|
|
28
29
|
def initialize(name)
|
29
30
|
@children = {}
|
30
|
-
|
31
|
-
@parameter = name[1..-1].to_sym
|
32
|
-
@value = WILD_PLACEHOLDER
|
33
|
-
elsif name[0, 1] == '*'
|
34
|
-
@parameter = if name[1..-1].empty?
|
35
|
-
:wildpath
|
36
|
-
else
|
37
|
-
name[1..-1].to_sym
|
38
|
-
end
|
39
|
-
@value = STAR_PLACEHOLDER
|
40
|
-
else
|
41
|
-
@value = name
|
42
|
-
end
|
31
|
+
@value, @parameter = parse_name(name)
|
43
32
|
@extract_format = true
|
44
33
|
end
|
45
34
|
|
@@ -51,6 +40,19 @@ module Blix::Rest
|
|
51
40
|
@children[k] = v
|
52
41
|
end
|
53
42
|
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse_name(name)
|
46
|
+
case name[0]
|
47
|
+
when ':'
|
48
|
+
[WILD_PLACEHOLDER, name[1..].to_sym]
|
49
|
+
when '*'
|
50
|
+
[STAR_PLACEHOLDER, name[1..].empty? ? :wildpath : name[1..].to_sym]
|
51
|
+
else
|
52
|
+
[name, nil]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
54
56
|
end
|
55
57
|
|
56
58
|
class << self
|
@@ -58,18 +60,20 @@ module Blix::Rest
|
|
58
60
|
# the root always starts with '/' and finishes with '/'
|
59
61
|
def set_path_root(root)
|
60
62
|
root = root.to_s
|
61
|
-
root = '/' + root
|
62
|
-
root += '/'
|
63
|
+
root = '/' + root unless root.start_with?('/')
|
64
|
+
root += '/' unless root.end_with?('/')
|
63
65
|
@path_root = root
|
64
66
|
@path_root_length = @path_root.length - 1
|
65
67
|
end
|
66
68
|
|
69
|
+
# if the path_root has not been set then return '/'
|
67
70
|
def path_root
|
68
71
|
@path_root || '/'
|
69
72
|
end
|
70
73
|
|
74
|
+
# return 0 if the path_root has not been set
|
71
75
|
def path_root_length
|
72
|
-
@path_root_length
|
76
|
+
@path_root_length || 0
|
73
77
|
end
|
74
78
|
|
75
79
|
def full_path(path)
|
@@ -91,7 +95,7 @@ module Blix::Rest
|
|
91
95
|
|
92
96
|
def table
|
93
97
|
# compile the table in one thread only.
|
94
|
-
@table
|
98
|
+
@table || @@mutex.synchronize{@table ||= compile}
|
95
99
|
end
|
96
100
|
|
97
101
|
def dump
|
@@ -325,21 +329,25 @@ module Blix::Rest
|
|
325
329
|
end
|
326
330
|
str
|
327
331
|
end
|
328
|
-
|
329
332
|
end
|
330
333
|
|
331
334
|
end # RequestMapper
|
332
335
|
|
333
|
-
|
334
|
-
RequestMapper.set_path_root(*args)
|
335
|
-
end
|
336
|
+
class << self
|
336
337
|
|
337
|
-
def self.path_root
|
338
|
-
RequestMapper.path_root
|
339
|
-
end
|
340
338
|
|
341
|
-
|
342
|
-
|
339
|
+
def set_path_root(*args)
|
340
|
+
RequestMapper.set_path_root(*args)
|
341
|
+
end
|
342
|
+
|
343
|
+
def path_root
|
344
|
+
RequestMapper.path_root
|
345
|
+
end
|
346
|
+
|
347
|
+
def full_path(path)
|
348
|
+
RequestMapper.full_path(path)
|
349
|
+
end
|
350
|
+
|
343
351
|
end
|
344
352
|
|
345
353
|
RequestMapper.set_path_root(ENV['BLIX_REST_ROOT']) if ENV['BLIX_REST_ROOT']
|
data/lib/blix/rest/response.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# pass a response object to the controller to set
|
2
2
|
# header status and content.
|
3
3
|
|
4
|
+
unless defined?(Rack::Headers)
|
5
|
+
class Rack::Headers < Hash; end
|
6
|
+
end
|
7
|
+
|
4
8
|
module Blix::Rest
|
5
9
|
|
6
10
|
|
@@ -22,5 +26,11 @@ module Blix::Rest
|
|
22
26
|
@headers.merge!(headers) if headers
|
23
27
|
end
|
24
28
|
|
29
|
+
def set_options(options={})
|
30
|
+
@status = options[:status].to_i if options[:status]
|
31
|
+
@headers.merge!(options[:headers]) if options[:headers]
|
32
|
+
@headers['content-type'] = options[:content_type] if options[:content_type]
|
33
|
+
end
|
34
|
+
|
25
35
|
end
|
26
36
|
end
|
data/lib/blix/rest/server.rb
CHANGED
@@ -3,18 +3,11 @@
|
|
3
3
|
module Blix::Rest
|
4
4
|
class Server
|
5
5
|
|
6
|
-
def initialize(
|
6
|
+
def initialize(options = {})
|
7
7
|
@_parsers = {}
|
8
8
|
@_mime_types = {}
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
register_parser('html', HtmlFormatParser.new)
|
13
|
-
register_parser('json', JsonFormatParser.new)
|
14
|
-
register_parser('xml', XmlFormatParser.new)
|
15
|
-
register_parser('raw', RawFormatParser.new)
|
16
|
-
extract_parsers_from_options(opts)
|
17
|
-
@_options = opts
|
9
|
+
@_options = options
|
10
|
+
setup_parsers(options)
|
18
11
|
end
|
19
12
|
|
20
13
|
# options passed to the server
|
@@ -22,7 +15,6 @@ module Blix::Rest
|
|
22
15
|
@_options
|
23
16
|
end
|
24
17
|
|
25
|
-
|
26
18
|
# the object serving as a cache
|
27
19
|
def _cache
|
28
20
|
@_cache ||= begin
|
@@ -36,16 +28,15 @@ module Blix::Rest
|
|
36
28
|
end
|
37
29
|
end
|
38
30
|
|
39
|
-
def extract_parsers_from_options(
|
40
|
-
|
41
|
-
next unless k =~ /^(\w*)_parser
|
31
|
+
def extract_parsers_from_options(options)
|
32
|
+
options.each do |k, v|
|
33
|
+
next unless k =~ /^(\w*)_parser$/
|
42
34
|
|
43
35
|
format = Regexp.last_match(1)
|
44
36
|
parser = v
|
45
37
|
register_parser(format, parser)
|
46
38
|
end
|
47
39
|
end
|
48
|
-
|
49
40
|
def set_custom_headers(format, headers)
|
50
41
|
parser = get_parser(format)
|
51
42
|
raise "parser not found for custom headers format=>#{format}" unless parser
|
@@ -61,7 +52,7 @@ module Blix::Rest
|
|
61
52
|
end
|
62
53
|
|
63
54
|
def register_parser(format, parser)
|
64
|
-
raise "#{
|
55
|
+
raise "#{format} must be an object with parent class Blix::Rest::FormatParser" unless parser.is_a?(FormatParser)
|
65
56
|
|
66
57
|
parser._format = format
|
67
58
|
@_parsers[format.to_s.downcase] = parser
|
@@ -71,7 +62,7 @@ module Blix::Rest
|
|
71
62
|
# retrieve parameters from the http request
|
72
63
|
def retrieve_params(env)
|
73
64
|
post_params = {}
|
74
|
-
body
|
65
|
+
body = ''
|
75
66
|
params = env['params'] || {}
|
76
67
|
params.merge!(::Rack::Utils.parse_nested_query(env['QUERY_STRING']))
|
77
68
|
|
@@ -85,19 +76,15 @@ module Blix::Rest
|
|
85
76
|
post_params = {}
|
86
77
|
else
|
87
78
|
begin
|
88
|
-
post_params = case
|
79
|
+
post_params = case env['CONTENT_TYPE']
|
89
80
|
when URL_ENCODED
|
90
81
|
::Rack::Utils.parse_nested_query(body)
|
91
|
-
when JSON_ENCODED
|
82
|
+
when JSON_ENCODED
|
92
83
|
json = MultiJson.load(body)
|
93
|
-
|
94
|
-
json
|
95
|
-
else
|
96
|
-
{ '_json' => json }
|
97
|
-
end
|
84
|
+
json.is_a?(Hash) ? json : { '_json' => json }
|
98
85
|
else
|
99
86
|
{}
|
100
|
-
|
87
|
+
end
|
101
88
|
rescue StandardError => e
|
102
89
|
raise BadRequestError, "Invalid parameters: #{e.class}"
|
103
90
|
end
|
@@ -124,13 +111,22 @@ module Blix::Rest
|
|
124
111
|
case mime
|
125
112
|
when 'application/json' then :json
|
126
113
|
when 'text/html' then :html
|
127
|
-
when 'application/xml'
|
114
|
+
when 'application/xml' then :xml
|
128
115
|
when 'application/xhtml+xml' then :xhtml
|
129
116
|
when '*/*' then :*
|
130
117
|
end
|
131
118
|
end
|
132
119
|
|
133
|
-
|
120
|
+
def setup_parsers(options)
|
121
|
+
# Register default parsers
|
122
|
+
register_parser('html', HtmlFormatParser.new)
|
123
|
+
register_parser('json', JsonFormatParser.new)
|
124
|
+
register_parser('xml', XmlFormatParser.new)
|
125
|
+
register_parser('raw', RawFormatParser.new)
|
126
|
+
extract_parsers_from_options(options)
|
127
|
+
end
|
128
|
+
|
129
|
+
# attempt to handle multiple accept formats here..
|
134
130
|
# mime can include '.../*' and '*/*'
|
135
131
|
# FIXME
|
136
132
|
def get_format_new(env, options)
|
@@ -156,28 +152,25 @@ module Blix::Rest
|
|
156
152
|
|
157
153
|
# the call function is the interface with the rack framework
|
158
154
|
def call(env)
|
155
|
+
t1 = Time.now
|
159
156
|
req = Rack::Request.new(env)
|
160
157
|
|
161
|
-
verb
|
162
|
-
path
|
163
|
-
path
|
158
|
+
verb = env['REQUEST_METHOD']
|
159
|
+
path = req.path
|
160
|
+
path = CGI.unescape(path) unless _options[:unescape] == false
|
164
161
|
|
165
162
|
blk, path_params, options, is_wild = RequestMapper.match(verb, path)
|
166
163
|
|
167
164
|
match_all = RequestMapper.match('ALL', path) unless blk && !is_wild
|
168
|
-
blk, path_params, options = match_all if match_all && match_all[0]
|
169
|
-
|
165
|
+
blk, path_params, options = match_all if match_all && match_all[0]
|
170
166
|
|
171
167
|
default_format = options && options[:default] && options[:default].to_sym
|
172
|
-
force_format
|
173
|
-
do_cache
|
174
|
-
clear_cache
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
format = query_format || path_params[:format] || get_format_new(env, options) || default_format || :json
|
179
|
-
|
180
|
-
parser = get_parser(force_format || format)
|
168
|
+
force_format = options && options[:force] && options[:force].to_sym
|
169
|
+
do_cache = options && options[:cache] && !Blix::Rest.cache_disabled
|
170
|
+
clear_cache = options && options[:cache_reset]
|
171
|
+
query_format = options && options[:query] && req.GET['format'] && req.GET['format'].to_sym
|
172
|
+
format = query_format || path_params[:format] || get_format_new(env, options) || default_format || :json
|
173
|
+
parser = get_parser(force_format || format)
|
181
174
|
|
182
175
|
unless parser
|
183
176
|
if blk
|
@@ -189,54 +182,59 @@ module Blix::Rest
|
|
189
182
|
|
190
183
|
parser._options = options
|
191
184
|
|
192
|
-
# check for cached response
|
193
|
-
#
|
194
|
-
if do_cache && ( response = _cache["#{verb}|#{format}|#{path}"] )
|
185
|
+
# check for cached response and return with cached response if found.
|
186
|
+
if do_cache && (response = _cache["#{verb}|#{format}|#{path}"])
|
195
187
|
return [response.status, response.headers.merge('x-blix-cache' => 'cached'), response.content]
|
196
188
|
end
|
197
189
|
|
198
190
|
response = Response.new
|
199
191
|
|
200
192
|
if blk
|
201
|
-
|
202
193
|
begin
|
203
194
|
params = env['params']
|
204
195
|
context = Context.new(path_params, params, req, format, response, verb, self)
|
205
|
-
value
|
196
|
+
value = blk.call(context)
|
197
|
+
response_options = context.response_options || {}
|
206
198
|
rescue ServiceError => e
|
207
|
-
set_default_headers(parser,response)
|
199
|
+
set_default_headers(parser, response)
|
208
200
|
response.set(e.status, parser.format_error(e.message), e.headers)
|
201
|
+
logger << e.message if $VERBOSE
|
209
202
|
rescue RawResponse => e
|
210
203
|
value = e.content
|
211
|
-
value = [value.to_s] unless value.respond_to?(:each) ||
|
212
|
-
response.status
|
204
|
+
value = [value.to_s] unless value.respond_to?(:each) || value.respond_to?(:call)
|
205
|
+
response.status = e.status if e.status
|
213
206
|
response.content = value
|
214
207
|
response.headers.merge!(e.headers) if e.headers
|
215
208
|
rescue AuthorizationError => e
|
216
|
-
set_default_headers(parser,response)
|
209
|
+
set_default_headers(parser, response)
|
217
210
|
response.set(401, parser.format_error(e.message), AUTH_HEADER => "#{e.type} realm=\"#{e.realm}\", charset=\"UTF-8\"")
|
218
211
|
rescue Exception => e
|
219
|
-
set_default_headers(parser,response)
|
212
|
+
set_default_headers(parser, response)
|
220
213
|
response.set(500, parser.format_error('internal error'))
|
221
|
-
|
222
|
-
|
214
|
+
logger << e.message
|
215
|
+
logger << e.backtrace.join("\n")
|
223
216
|
else # no error
|
224
|
-
|
225
|
-
|
217
|
+
response.set_options(response_options)
|
218
|
+
if response_options[:raw]
|
219
|
+
response.content = value
|
220
|
+
else
|
221
|
+
set_default_headers(parser, response)
|
222
|
+
parser.format_response(value, response)
|
223
|
+
end
|
226
224
|
# cache response if requested
|
227
225
|
_cache.clear if clear_cache
|
228
226
|
_cache["#{verb}|#{format}|#{path}"] = response if do_cache
|
229
227
|
end
|
230
|
-
|
231
228
|
else
|
232
|
-
set_default_headers(parser,response)
|
229
|
+
set_default_headers(parser, response)
|
233
230
|
response.set(404, parser.format_error('Invalid Url'))
|
234
231
|
end
|
235
232
|
|
233
|
+
logger << "#{verb} #{path} total time=#{((Time.now - t1) * 1000).round(2)}ms" if $VERBOSE
|
236
234
|
[response.status.to_i, response.headers, response.content]
|
237
235
|
end
|
238
236
|
|
239
|
-
def set_default_headers(parser,response)
|
237
|
+
def set_default_headers(parser, response)
|
240
238
|
if parser.__custom_headers
|
241
239
|
response.headers.merge! parser.__custom_headers
|
242
240
|
else
|
@@ -244,5 +242,10 @@ module Blix::Rest
|
|
244
242
|
end
|
245
243
|
end
|
246
244
|
|
245
|
+
private
|
246
|
+
|
247
|
+
def logger
|
248
|
+
Blix::Rest.logger
|
249
|
+
end
|
247
250
|
end
|
248
251
|
end
|
data/lib/blix/rest/session.rb
CHANGED
@@ -26,6 +26,11 @@ module Blix::Rest
|
|
26
26
|
self.class.get_session_manager
|
27
27
|
end
|
28
28
|
|
29
|
+
def session_skip_update
|
30
|
+
@__session_id = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
|
29
34
|
def session_name
|
30
35
|
self.class.get_session_name
|
31
36
|
end
|
@@ -67,9 +72,9 @@ module Blix::Rest
|
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
70
|
-
if opts[:csrf]
|
71
|
-
if env["HTTP_X_CSRF_TOKEN"] != csrf_token
|
72
|
-
send_error("
|
75
|
+
if opts[:csrf] && (ENV['RACK_ENV']!='test')
|
76
|
+
if env["HTTP_X_CSRF_TOKEN"] != csrf_token
|
77
|
+
send_error("error [0100]")
|
73
78
|
end
|
74
79
|
end
|
75
80
|
|
data/lib/blix/rest/version.rb
CHANGED
data/lib/blix/rest.rb
CHANGED
@@ -33,6 +33,10 @@ module Blix
|
|
33
33
|
@_environment ||= ENV['RACK_ENV'] || 'development'
|
34
34
|
end
|
35
35
|
|
36
|
+
def self.init
|
37
|
+
RequestMapper.table # compile the table
|
38
|
+
end
|
39
|
+
|
36
40
|
def self.environment?(val)
|
37
41
|
environment == val.to_s
|
38
42
|
end
|
@@ -127,6 +131,8 @@ module Blix
|
|
127
131
|
@type = type || 'Basic'
|
128
132
|
end
|
129
133
|
end
|
134
|
+
|
135
|
+
class RateError < StandardError; end
|
130
136
|
end
|
131
137
|
end
|
132
138
|
|
@@ -154,6 +160,7 @@ require 'blix/rest/response'
|
|
154
160
|
require 'blix/rest/format_parser'
|
155
161
|
require 'blix/rest/request_mapper'
|
156
162
|
require 'blix/rest/cache'
|
163
|
+
require 'blix/rest/memory_cache'
|
157
164
|
require 'blix/rest/server'
|
158
165
|
require 'blix/rest/route'
|
159
166
|
require 'blix/rest/controller'
|
data/lib/blix/utils/misc.rb
CHANGED
@@ -7,6 +7,45 @@ module Blix
|
|
7
7
|
Dir.glob("#{path}/*.rb").each {|file| require File.expand_path(file)[0..-4] }
|
8
8
|
end
|
9
9
|
|
10
|
+
def self.klass_to_name(klass)
|
11
|
+
return unless klass
|
12
|
+
klass = klass.to_s.split('::')[-1]
|
13
|
+
klass.gsub(/([a-z]+)([A-Z]+)/){"#{$1}_#{$2}"}.downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.name_to_klass(name)
|
17
|
+
construct_klass(name)
|
18
|
+
end
|
19
|
+
|
20
|
+
# construct a klass from a name
|
21
|
+
def self.construct_klass(name)
|
22
|
+
name && name.to_s.downcase.split('_').map(&:capitalize).join
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.construct_singular(name)
|
26
|
+
name && name.to_s.sub(/s$/,'')
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.construct_plural(name)
|
30
|
+
name && name.plural
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.camelcase(str)
|
34
|
+
downcase_front(construct_klass(str))
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.downcase_front(str)
|
38
|
+
str[0, 1].downcase + str[1..-1]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.underscore(str)
|
42
|
+
str.gsub(/::/, '/')
|
43
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
44
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
45
|
+
.tr('-', '_')
|
46
|
+
.downcase
|
47
|
+
end
|
48
|
+
|
10
49
|
|
11
50
|
|
12
51
|
# filter the hash using the supplied filter
|