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.
@@ -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
@@ -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 fold
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
@@ -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'
@@ -14,13 +14,13 @@ class Rack::RSI
14
14
 
15
15
  class RsiRender
16
16
 
17
- def initialize( app, env, level = 0 )
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.esi'] }.any?
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
- return original_response unless rack_rsi_flag
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 = 0
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. Expect for Cache-Control, ETag, Expires, Last-Modified
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
@@ -1,6 +1,6 @@
1
1
  module Rack
2
2
  class RSI
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
6
6
 
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.1
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