rack-rsi 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/README.markdown +22 -1
- data/examples/hello_world_app.rb +57 -1
- data/lib/rack/rsi.rb +13 -7
- data/lib/rack/rsi_version.rb +1 -1
- metadata +2 -1
data/CHANGELOG
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
v 0.0.2
|
2
|
+
-------
|
3
|
+
* Improved Documentation
|
4
|
+
* Recursive rsi_include upto 5 levels.
|
5
|
+
* Application can choose to raise on errors or ignore erros when a
|
6
|
+
target is included
|
7
|
+
* Hello World Example extended to showcase rsi_include capability
|
8
|
+
* In-case of redirect and rack.rsi header set then assembly is not
|
9
|
+
invoked.
|
10
|
+
|
11
|
+
v 0.0.1
|
12
|
+
-------
|
13
|
+
* Supports ETag Header Tag
|
14
|
+
* Supports Cache-Control Header Tag
|
15
|
+
* Supports Content-Length Header Tag
|
data/README.markdown
CHANGED
@@ -91,10 +91,31 @@ in view template foo_action.html.erb
|
|
91
91
|
<%%= rsi_include( '/path/to_include' ) %>
|
92
92
|
...
|
93
93
|
|
94
|
+
NOTE please make sure you write the target path as strings rather than
|
95
|
+
method names e.g.:
|
96
|
+
|
97
|
+
...
|
98
|
+
<%%= rsi_include( '/contacts/1' ) %>
|
99
|
+
...
|
100
|
+
|
101
|
+
Or if you want to use path helpers than trick ERB to generate ERB tags
|
102
|
+
as follows:
|
103
|
+
|
104
|
+
...
|
105
|
+
<%= "<%= rsi_include( '#{contact_path(1)}' ) ".html_safe %> %>
|
106
|
+
...
|
107
|
+
|
94
108
|
How do I use it with Bare Rack Apps
|
95
109
|
-----------------------------------
|
96
110
|
|
97
|
-
look for hello_world_app.rb in examples
|
111
|
+
look for hello_world_app.rb in examples folder
|
112
|
+
|
113
|
+
cd examples
|
114
|
+
rackup
|
115
|
+
open http://127.0.0.1:9292/
|
116
|
+
open http://127.0.0.1:9292/recursive
|
117
|
+
open http://127.0.0.1:9292/noerror
|
118
|
+
open http://127.0.0.1:9292/error
|
98
119
|
|
99
120
|
|
100
121
|
Limitations
|
data/examples/hello_world_app.rb
CHANGED
@@ -24,8 +24,64 @@ class HelloWorldApp
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
ACTIONS = %<index header footer>
|
27
|
+
ACTIONS = %<index header footer recursive error noerror>
|
28
28
|
|
29
|
+
# Output /error
|
30
|
+
# Raises Exception
|
31
|
+
def error(request, response)
|
32
|
+
response['rack.rsi'] = '1'
|
33
|
+
response['Cache-Control'] = 'max-age=10'
|
34
|
+
# depth if set as a param will be string rather than integer
|
35
|
+
# depth + 1 in line 36 should raise error on recursive call
|
36
|
+
depth = request.params['depth'] || 1
|
37
|
+
response.write(%{
|
38
|
+
<%= rsi_include( "/error?depth=#{depth+1}", :raise_on_error ) %>
|
39
|
+
<p>Hello World! #{depth}</p>
|
40
|
+
}.gsub(/^\s*/, "").strip)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Output /noerror
|
44
|
+
# Hello World! 1
|
45
|
+
def noerror(request, response)
|
46
|
+
response['rack.rsi'] = '1'
|
47
|
+
response['Cache-Control'] = 'max-age=10'
|
48
|
+
# depth if set as a param will be string rather than integer
|
49
|
+
# depth + 1 in line 36 should raise error on recursive call
|
50
|
+
# which is silently ignore
|
51
|
+
depth = request.params['depth'] || 1
|
52
|
+
response.write(%{
|
53
|
+
<%= rsi_include( "/error?depth=#{depth+1}" ) %>
|
54
|
+
<p>Hello World! #{depth}</p>
|
55
|
+
}.gsub(/^\s*/, "").strip)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Output /recursive
|
59
|
+
# Hello World! 5
|
60
|
+
#
|
61
|
+
# Hello World! 4
|
62
|
+
#
|
63
|
+
# Hello World! 3
|
64
|
+
#
|
65
|
+
# Hello World! 2
|
66
|
+
#
|
67
|
+
# Hello World! 1
|
68
|
+
def recursive(request, response)
|
69
|
+
response['rack.rsi'] = '1'
|
70
|
+
response['Cache-Control'] = 'max-age=10'
|
71
|
+
depth = ( request.params['depth'] || 1 ).to_i
|
72
|
+
response.write(%{
|
73
|
+
<%= rsi_include( "/recursive?depth=#{depth+1}", :raise_on_error ) %>
|
74
|
+
<p>Hello World! #{depth}</p>
|
75
|
+
}.gsub(/^\s*/, "").strip)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Output /
|
79
|
+
# Here comes header from Header Action exclusively for buzzmenot
|
80
|
+
#
|
81
|
+
# Hello World!
|
82
|
+
#
|
83
|
+
# Here comes footer from Footer Action exclusively for github
|
84
|
+
#
|
29
85
|
def index(request, response)
|
30
86
|
response['rack.rsi'] = '1'
|
31
87
|
response['Cache-Control'] = 'max-age=3600'
|
data/lib/rack/rsi.rb
CHANGED
@@ -14,13 +14,13 @@ class Rack::RSI
|
|
14
14
|
|
15
15
|
class RsiRender
|
16
16
|
|
17
|
-
def initialize( app, env, level =
|
17
|
+
def initialize( app, env, level = 1 )
|
18
18
|
@app, @env, @level = app, env, level
|
19
19
|
@headers, @body = {}, {}
|
20
20
|
end
|
21
21
|
|
22
22
|
def rack_rsi?
|
23
|
-
@headers.values.select{ |x| x && x['rack.
|
23
|
+
@headers.values.select{ |x| x && x['rack.rsi'] }.any?
|
24
24
|
end
|
25
25
|
|
26
26
|
def cache_control_headers
|
@@ -31,7 +31,8 @@ class Rack::RSI
|
|
31
31
|
return binding( )
|
32
32
|
end
|
33
33
|
|
34
|
-
def rsi_include( source )
|
34
|
+
def rsi_include( source, raise_on_error = false )
|
35
|
+
return "" unless @level < 5
|
35
36
|
uri = URI.parse( source )
|
36
37
|
include_env = @env.merge( "PATH_INFO" => uri.path,
|
37
38
|
"SCRIPT_NAME" => "",
|
@@ -42,6 +43,7 @@ class Rack::RSI
|
|
42
43
|
@headers[ source ] = include_headers
|
43
44
|
@body[ source ] = ( include_status == 200 ? include_body : [] )
|
44
45
|
rescue Exception => message
|
46
|
+
raise message if raise_on_error
|
45
47
|
@body[ source ] = []
|
46
48
|
end
|
47
49
|
value = ''
|
@@ -68,7 +70,10 @@ class Rack::RSI
|
|
68
70
|
status, headers, enumerable_body = original_response = @app.call(env)
|
69
71
|
|
70
72
|
rack_rsi_flag = headers.delete('rack.rsi')
|
71
|
-
|
73
|
+
|
74
|
+
# Assemble Pages if rack_rsi_flag is set and status is 200 ok
|
75
|
+
# otherwise return the original response
|
76
|
+
return original_response unless rack_rsi_flag && status == 200
|
72
77
|
|
73
78
|
body = ""
|
74
79
|
enumerable_body.each do |part|
|
@@ -78,7 +83,7 @@ class Rack::RSI
|
|
78
83
|
cache_control_headers = Array( headers.delete( 'Cache-Control' ) || "max-age=0" )
|
79
84
|
|
80
85
|
# Like Varnish supports upto 5 levels of ESI includes recursively
|
81
|
-
level =
|
86
|
+
level = 1
|
82
87
|
while( rack_rsi_flag )
|
83
88
|
erb = ERB.new( body, 0 )
|
84
89
|
renderer = RsiRender.new( vanilla_app, vanilla_env, level )
|
@@ -94,7 +99,8 @@ class Rack::RSI
|
|
94
99
|
|
95
100
|
# For Assembled Pages Cache-Control to be set as private, with
|
96
101
|
# max-age=<minimum max-age of all the requests that are assembled>
|
97
|
-
# and should be revalidate on stale
|
102
|
+
# and should be revalidate on stale. If max-age is not set for even one of the
|
103
|
+
# requests then max-age is set to 0.
|
98
104
|
min_max_age = cache_control_headers.collect{ |x| x.match(/max-age\s*=\s*(\d+)/).to_a[1].to_i }.min
|
99
105
|
|
100
106
|
headers['Cache-Control'] = "private, max-age=#{min_max_age}, must-revalidate"
|
@@ -105,7 +111,7 @@ class Rack::RSI
|
|
105
111
|
headers['Content-Length'] = Rack::Utils.bytesize( body ).to_s
|
106
112
|
|
107
113
|
# For now whatever headers is set by the original action would be
|
108
|
-
# passed on.
|
114
|
+
# passed on. Except for Cache-Control, ETag, Expires, Last-Modified
|
109
115
|
# Cookies from the original action are passed on.
|
110
116
|
[ status, headers, [ body ] ]
|
111
117
|
end
|
data/lib/rack/rsi_version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rack-rsi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ram Singla
|
@@ -35,6 +35,7 @@ extra_rdoc_files: []
|
|
35
35
|
|
36
36
|
files:
|
37
37
|
- .gitignore
|
38
|
+
- CHANGELOG
|
38
39
|
- Gemfile
|
39
40
|
- LICENSE.markdown
|
40
41
|
- README.markdown
|