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.
@@ -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