blix-rest 0.1.30 → 0.8.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/LICENSE +2 -2
- data/README.md +232 -30
- data/lib/blix/rest/cache.rb +79 -0
- data/lib/blix/rest/controller.rb +202 -29
- data/lib/blix/rest/cucumber/world.rb +13 -12
- data/lib/blix/rest/format_parser.rb +18 -11
- data/lib/blix/rest/redis_cache.rb +127 -0
- data/lib/blix/rest/request_mapper.rb +22 -6
- data/lib/blix/rest/response.rb +2 -2
- data/lib/blix/rest/route.rb +33 -0
- data/lib/blix/rest/server.rb +60 -20
- data/lib/blix/rest/session.rb +138 -0
- data/lib/blix/rest/version.rb +1 -1
- data/lib/blix/rest.rb +31 -10
- data/lib/blix/utils/redis_store.rb +2 -2
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5db97b519f38052ee2b7272f3a25d6ec4d5e3ba71cae44bdcd83e25cdd6902f2
|
4
|
+
data.tar.gz: e7fb1c1da94eb622629a718bd81763d6874dc14028bed0ba8328b42cac5c2152
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb48999da4fffe47e1d52cb85319c7ed6473c756a55d6e87edef288a9a118f971c90d709ea73aaf566e1f927a7779056547a91d1cfae71b2cd1a157658c3d2a4
|
7
|
+
data.tar.gz: 93d06074a5b66da9099c1d1bee4fb23a00ac18f994809efb9fb28f0be7d6bf3a889fdad45a2fb349dbabeec6c816c77a34975a8cd7de70efbcce4cff2af1acb2
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2017 Clive Andrews
|
3
|
+
Copyright (c) 2017-2020 Clive Andrews
|
4
4
|
|
5
5
|
|
6
6
|
Permission is hereby granted, free of charge, to any person
|
@@ -22,4 +22,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
22
22
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23
23
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24
24
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
25
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -71,7 +71,7 @@ if there is a more specific path then it will be used first :
|
|
71
71
|
### Path options
|
72
72
|
|
73
73
|
:accept : the format or formats to accept eg: :html or [:png, :jpeg]
|
74
|
-
:default : default format if not derived through
|
74
|
+
:default : default format if not derived through other means.
|
75
75
|
:force : force response into the given format
|
76
76
|
:query : derive format from request query (default: false)
|
77
77
|
:extension : derive format from path extension (default: true)
|
@@ -189,10 +189,19 @@ use the following to accept requests in a special format ..
|
|
189
189
|
|
190
190
|
get '/custom', :accept=>:xyz, :force=>:raw do
|
191
191
|
add_headers 'Content-Type'=>'text/xyz'
|
192
|
-
|
193
192
|
"xyz"
|
194
193
|
end
|
195
194
|
|
195
|
+
|
196
|
+
Alternatively it is possible to raise a RawResponse:
|
197
|
+
|
198
|
+
add_headers 'Content-Type'=>'text/xyz'
|
199
|
+
raise RawResponse, 'xyz'
|
200
|
+
|
201
|
+
or with status and headers:
|
202
|
+
|
203
|
+
raise RawResponse.new('xyz', 123, 'Content-Type'=>'text/xyz')
|
204
|
+
|
196
205
|
## FORMATS
|
197
206
|
|
198
207
|
the format of a request is derived from
|
@@ -218,32 +227,40 @@ base class for controllers. within your block handling a particular route you
|
|
218
227
|
have access to a number of methods
|
219
228
|
|
220
229
|
|
221
|
-
env
|
222
|
-
method
|
223
|
-
req
|
224
|
-
body
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
230
|
+
env : the request environment hash
|
231
|
+
method : the request method lowercase( 'get'/'post' ..)
|
232
|
+
req : the rack request
|
233
|
+
body : the request body as a string
|
234
|
+
path : the request path
|
235
|
+
query_params : a hash of parameters as passed in the url as parameters
|
236
|
+
path_params : a hash of parameters constructed from variable parts of the path
|
237
|
+
post_params : a hash of parameters passed in the body of the request
|
238
|
+
params : all the params combined
|
239
|
+
user : the user making this request ( or nil if
|
240
|
+
format : the format the response should be in :json or :html
|
241
|
+
before : before hook ( opts ) - remember to add 'super' as first line !!!
|
242
|
+
after : after hook (opts,response)- remember to add 'super' as first line !!!
|
243
|
+
proxy : forward the call to another service (service,path, opts={}) , :include_query=>true/false
|
244
|
+
session : req.session
|
245
|
+
redirect : (path, status=302) redirect to another url.
|
246
|
+
request_ip : the ip of the request
|
247
|
+
render_erb : (template_name [,:layout=>name])
|
248
|
+
server_cache : get the server cache object
|
249
|
+
server_cache_get : retrieve/store value in cache
|
250
|
+
path_for : (path) give the external path for an internal path
|
251
|
+
url_for : (path) give the full url for an internal path
|
252
|
+
h : escape html string to avoid XSS
|
253
|
+
escape_javascript : escape a javascript string
|
254
|
+
server_options : options as passed to server at create time
|
255
|
+
logger : system logger
|
256
|
+
mode_test? : test mode ?
|
257
|
+
mode_production? : production mode ?
|
258
|
+
mode_development? : development mode?
|
259
|
+
send_data : send raw data (data, options )
|
260
|
+
[:type=>mimetype]
|
261
|
+
[:filename=>name]
|
262
|
+
[:disposition=>inline|attachment]
|
263
|
+
[:status=>234]
|
247
264
|
|
248
265
|
get_session_id(session_name, opts={}) :
|
249
266
|
refresh_session_id(session_name, opts={}) :
|
@@ -252,6 +269,50 @@ to accept requests other than json then set `:accept=>[:json,:html]` as options
|
|
252
269
|
|
253
270
|
eg `post '/myform' :accept=>[:html] # this will only accept html requests.`
|
254
271
|
|
272
|
+
### Hooks
|
273
|
+
|
274
|
+
a before or after hook can be defined on a controller. Only define the hook once
|
275
|
+
for a given controller per source file. A hook included from another source file
|
276
|
+
is ok though.
|
277
|
+
|
278
|
+
class MyController < Blix::Rest::Controller
|
279
|
+
|
280
|
+
before do
|
281
|
+
...
|
282
|
+
end
|
283
|
+
|
284
|
+
after do
|
285
|
+
...
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
|
291
|
+
#### manipulate the route path or options
|
292
|
+
|
293
|
+
the `before_route` hook can be used to modify the path or options of a route.
|
294
|
+
|
295
|
+
the verb can not be modified
|
296
|
+
|
297
|
+
example:
|
298
|
+
|
299
|
+
class MyController < Blix::Rest::Controller
|
300
|
+
|
301
|
+
before_route do |route|
|
302
|
+
route.default_option(:level,:visitor)
|
303
|
+
route.prefix_path('/app')
|
304
|
+
end
|
305
|
+
...
|
306
|
+
end
|
307
|
+
|
308
|
+
the following methods are available on the route:
|
309
|
+
|
310
|
+
verb # readonly, the 'GET','POST' etc verb of the route
|
311
|
+
path # the path of the route
|
312
|
+
options # the options associated with the route eg :accept
|
313
|
+
path_prefix('/xx') # ensure the path has the given prefix
|
314
|
+
default_option(:xxx,'foo') # ensure that option has the given default value
|
315
|
+
|
255
316
|
### Sessions
|
256
317
|
|
257
318
|
the following methods are available in the controller for managing sessions.
|
@@ -266,13 +327,151 @@ this will generate a new session_id and setup the relevant headers
|
|
266
327
|
|
267
328
|
options can include:
|
268
329
|
|
269
|
-
:secure => true
|
270
|
-
:http = >true
|
330
|
+
:secure => true # secure cookies only
|
331
|
+
:http = >true # cookies for http only not javascript requests
|
271
332
|
:samesite =>:strict # use strict x-site policy
|
272
333
|
:samesite =>:lax # use lax x-site policy
|
273
334
|
|
335
|
+
For more complete session management:
|
336
|
+
|
337
|
+
class MyController < Blix::Rest::Controller
|
338
|
+
include Blix::Rest::Session
|
339
|
+
|
340
|
+
session_name :xxx # optional default'blix'
|
341
|
+
session_opts :http=>true # optional
|
342
|
+
session_manager: MyManager.new # optional , default Blix::Redis::Store
|
343
|
+
|
344
|
+
|
345
|
+
def myroutine
|
346
|
+
@xxx = session['xxx']
|
347
|
+
|
348
|
+
session['yyy'] = true
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
options can include:
|
354
|
+
|
355
|
+
:secure # false
|
356
|
+
:http # false
|
357
|
+
:samesite # lax
|
358
|
+
:path # '/'
|
359
|
+
:expire_secs # 30 mins
|
360
|
+
:cleanup_every_secs # 5 minutes
|
361
|
+
:max_age # nil
|
362
|
+
|
363
|
+
the following methods are available:
|
364
|
+
|
365
|
+
reset_session # gen new session id
|
366
|
+
session # session hash
|
367
|
+
csrf_token # the session csrf token
|
368
|
+
|
369
|
+
route options that affect sessions:
|
370
|
+
|
371
|
+
:nosession=>true # no session will be set/retrieved
|
372
|
+
:cache=>true # no session will be set/retrieved
|
373
|
+
:csrf=>true # request will be validated for calid csrf token.
|
374
|
+
# token must be in header X_CSRF_TOKEN field
|
274
375
|
|
376
|
+
session configuration is inherited from superclass controllers unless overridden.
|
275
377
|
|
378
|
+
## Cache
|
379
|
+
|
380
|
+
|
381
|
+
the server has a cache which can also be used for storing your own data.
|
382
|
+
|
383
|
+
within a controller access the controller with `server_cache` which returns the
|
384
|
+
cache object.
|
385
|
+
|
386
|
+
cache object methods:
|
387
|
+
|
388
|
+
get(key) # return value from the cache or nil
|
389
|
+
set(key,value) # set a value in the cache
|
390
|
+
key?(key) # is a key present in the cache
|
391
|
+
delete(key) # delete a key from the cache
|
392
|
+
clear # delete all keys from the cache.
|
393
|
+
|
394
|
+
there is also a `server_cache_get` method.
|
395
|
+
|
396
|
+
server_cache_get(key){ action }
|
397
|
+
|
398
|
+
get the value from the cache. If the key is missing in the cache then perform
|
399
|
+
the action in the provided block and store the result in the cache.
|
400
|
+
|
401
|
+
the default cache is just a ruby hash in memory. Pass a custom cache to
|
402
|
+
when creating a server with the `:cache` parameter.
|
403
|
+
|
404
|
+
class MyCache < Blix::Rest::Cache
|
405
|
+
def get(key)
|
406
|
+
..
|
407
|
+
end
|
408
|
+
|
409
|
+
def set(key,value)
|
410
|
+
..
|
411
|
+
end
|
412
|
+
|
413
|
+
def key?(key)
|
414
|
+
..
|
415
|
+
end
|
416
|
+
|
417
|
+
def delete(key)
|
418
|
+
..
|
419
|
+
end
|
420
|
+
|
421
|
+
def clear
|
422
|
+
..
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
cache = MyCache.new
|
427
|
+
|
428
|
+
app = Blix::Rest::Server.new(:cache=>cache)
|
429
|
+
|
430
|
+
there is a redis cache already defined:
|
431
|
+
|
432
|
+
require 'blix/rest/redis_cache'
|
433
|
+
|
434
|
+
cache = Blix::Rest::RedisCache.new(:expire_secs=>60*60*24) # expire after 1 day
|
435
|
+
run Blix::Rest::Server.new(:cache=>cache)
|
436
|
+
|
437
|
+
|
438
|
+
### automatically cache server responses
|
439
|
+
|
440
|
+
add `:cache=>true` to your route options in order to cache this route.
|
441
|
+
|
442
|
+
add `:cache_reset=>true` to your route options if the cache should be cleared when
|
443
|
+
calling this route.
|
444
|
+
|
445
|
+
the cache is not used in development/testmode , only in production mode.
|
446
|
+
|
447
|
+
### IMPORTANT - DO NOT CACHE SESSION KEYS AND OTHER SPECIFIC DATA IN CACHE
|
448
|
+
|
449
|
+
only cache pages with **HEADERS** and **CONTENT** that is not user specific.
|
450
|
+
|
451
|
+
## CORS
|
452
|
+
|
453
|
+
cross origin site requests
|
454
|
+
|
455
|
+
MyController < Blix::Rest::Controller
|
456
|
+
|
457
|
+
get '/info/crosssite' do
|
458
|
+
set_accept_cors
|
459
|
+
{:data=>'foo'}
|
460
|
+
end
|
461
|
+
|
462
|
+
options '/info/' crosssite' do
|
463
|
+
set_accept_cors, :headers=>'Content-Type',
|
464
|
+
end
|
465
|
+
|
466
|
+
end
|
467
|
+
|
468
|
+
within an `options` response the following parameters can be passes.
|
469
|
+
|
470
|
+
:origin=>'www.othersite.com' # specify specific allowed origin.
|
471
|
+
:methods => [:get] # allowed methods
|
472
|
+
:max_age => 86400 # maximum age this auth is valid
|
473
|
+
:headers => ['Content-Type','X-OTHER'] # allow additional headers
|
474
|
+
:credentials => true # allow requests with credentials
|
276
475
|
|
277
476
|
## Views
|
278
477
|
|
@@ -362,6 +561,9 @@ NOTE : if you need to set up your database with users then you can use the follo
|
|
362
561
|
|
363
562
|
in features/support/world.rb .........
|
364
563
|
|
564
|
+
|
565
|
+
require 'blix/rest/cucumber'
|
566
|
+
|
365
567
|
class RestWorld
|
366
568
|
|
367
569
|
# add a hook to create the user in the database -
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Blix::Rest
|
2
|
+
|
3
|
+
# cache server responses
|
4
|
+
class Cache
|
5
|
+
|
6
|
+
attr_reader :params
|
7
|
+
|
8
|
+
def initialize(params={})
|
9
|
+
@params = params
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](key)
|
13
|
+
get(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(key,data)
|
17
|
+
set(key, data)
|
18
|
+
end
|
19
|
+
|
20
|
+
#--------------- redefine these methods ..
|
21
|
+
|
22
|
+
# clear all data from the cache
|
23
|
+
def clear
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# retrieve data from the cache
|
28
|
+
def get(key)
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
# set data in the cache
|
33
|
+
def set(key, data)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# is key present in the cache
|
38
|
+
def key?(key)
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(key)
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
#---------------------------------------------------------------------------
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# implement cache as a simple ruby hash
|
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
|