rack-rsi 0.0.1 → 0.0.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.
- 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
|