mongrel_esi 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/COPYING +53 -0
  2. data/LICENSE +471 -0
  3. data/README +186 -0
  4. data/Rakefile +141 -0
  5. data/bin/mongrel_esi +271 -0
  6. data/ext/esi/common.rl +41 -0
  7. data/ext/esi/esi_parser.c +387 -0
  8. data/ext/esi/extconf.rb +6 -0
  9. data/ext/esi/machine.rb +499 -0
  10. data/ext/esi/parser.c +1675 -0
  11. data/ext/esi/parser.h +113 -0
  12. data/ext/esi/parser.rb +49 -0
  13. data/ext/esi/parser.rl +398 -0
  14. data/ext/esi/ruby_esi.rl +135 -0
  15. data/ext/esi/run-test.rb +3 -0
  16. data/ext/esi/test/common.rl +41 -0
  17. data/ext/esi/test/parser.c +1676 -0
  18. data/ext/esi/test/parser.h +113 -0
  19. data/ext/esi/test/parser.rl +398 -0
  20. data/ext/esi/test/test.c +373 -0
  21. data/ext/esi/test1.rb +56 -0
  22. data/ext/esi/test2.rb +45 -0
  23. data/lib/esi/cache.rb +207 -0
  24. data/lib/esi/config.rb +154 -0
  25. data/lib/esi/dispatcher.rb +27 -0
  26. data/lib/esi/handler.rb +236 -0
  27. data/lib/esi/invalidator.rb +40 -0
  28. data/lib/esi/logger.rb +46 -0
  29. data/lib/esi/router.rb +84 -0
  30. data/lib/esi/tag/attempt.rb +6 -0
  31. data/lib/esi/tag/base.rb +85 -0
  32. data/lib/esi/tag/except.rb +24 -0
  33. data/lib/esi/tag/include.rb +190 -0
  34. data/lib/esi/tag/invalidate.rb +54 -0
  35. data/lib/esi/tag/try.rb +40 -0
  36. data/lib/multi_dirhandler.rb +70 -0
  37. data/setup.rb +1585 -0
  38. data/test/integration/basic_test.rb +39 -0
  39. data/test/integration/cache_test.rb +37 -0
  40. data/test/integration/docs/content/500.html +16 -0
  41. data/test/integration/docs/content/500_with_failover.html +16 -0
  42. data/test/integration/docs/content/500_with_failover_to_alt.html +8 -0
  43. data/test/integration/docs/content/ajax_test_page.html +15 -0
  44. data/test/integration/docs/content/cookie_variable.html +3 -0
  45. data/test/integration/docs/content/foo.html +15 -0
  46. data/test/integration/docs/content/include_in_include.html +15 -0
  47. data/test/integration/docs/content/malformed_transforms.html +16 -0
  48. data/test/integration/docs/content/malformed_transforms.html-correct +11 -0
  49. data/test/integration/docs/content/static-failover.html +20 -0
  50. data/test/integration/docs/content/test2.html +1 -0
  51. data/test/integration/docs/content/test3.html +17 -0
  52. data/test/integration/docs/esi_invalidate.html +6 -0
  53. data/test/integration/docs/esi_mixed_content.html +15 -0
  54. data/test/integration/docs/esi_test_content.html +27 -0
  55. data/test/integration/docs/index.html +688 -0
  56. data/test/integration/docs/test1.html +1 -0
  57. data/test/integration/docs/test3.html +9 -0
  58. data/test/integration/docs/test_failover.html +1 -0
  59. data/test/integration/handler_test.rb +270 -0
  60. data/test/integration/help.rb +234 -0
  61. data/test/net/get_test.rb +197 -0
  62. data/test/net/net_helper.rb +16 -0
  63. data/test/net/server_test.rb +249 -0
  64. data/test/unit/base_tag_test.rb +44 -0
  65. data/test/unit/esi-sample.html +56 -0
  66. data/test/unit/help.rb +77 -0
  67. data/test/unit/include_request_test.rb +69 -0
  68. data/test/unit/include_tag_test.rb +14 -0
  69. data/test/unit/parser_test.rb +478 -0
  70. data/test/unit/router_test.rb +34 -0
  71. data/test/unit/sample.html +21 -0
  72. data/tools/rakehelp.rb +119 -0
  73. metadata +182 -0
@@ -0,0 +1 @@
1
+ <div>test1</div>
@@ -0,0 +1,9 @@
1
+ <div>test3</div>
2
+ <esi:try>
3
+ <esi:attempt>
4
+ <esi:include src="/fragments/test1.html" max-age="600+600"/>
5
+ </esi:attempt>
6
+ <esi:except>
7
+ <esi:include src="/fragments/test1.html"/>
8
+ </esi:except>
9
+ </esi:try>
@@ -0,0 +1 @@
1
+ <div>test failover</div>
@@ -0,0 +1,270 @@
1
+ require "#{File.dirname(__FILE__)}/help"
2
+
3
+ class HandlerTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ ESI::Server.start
7
+ end
8
+
9
+ def test_more_web_server
10
+ results = hit([ "http://localhost:9997/esi_test_content.html", "http://localhost:9997/esi_mixed_content.html"])
11
+
12
+ results.each do |res|
13
+ assert_match $fragment_test1, res
14
+ assert_no_match /<esi:/, res # assert there are no esi tags in the result
15
+ end
16
+ check_status results, String
17
+ end
18
+
19
+ def test_simple_esi
20
+ Net::HTTP.start("localhost", 9997) do |h|
21
+ req = h.get("/esi_test_content.html")
22
+ assert_not_nil req
23
+ assert_not_nil req.header
24
+ assert_not_nil req.body
25
+ assert_equal Net::HTTPOK, req.header.class
26
+ assert_match $fragment_test1, req.body, "Fragment not found"
27
+ assert_match $fragment_test2, req.body, "Fragment not found"
28
+ end
29
+ end
30
+
31
+ def test_large_document
32
+ Net::HTTP.start("localhost", 9997) do |h|
33
+ req = h.get("/index.html")
34
+ assert_not_nil req
35
+ assert_not_nil req.header
36
+ assert_not_nil req.body
37
+ assert_equal Net::HTTPOK, req.header.class
38
+ assert_match $fragment_test1, req.body, "Fragment not found"
39
+ # should have 37 fragments
40
+ count = 0
41
+ req.body.scan $fragment_test1 do|m|
42
+ count += 1
43
+ end
44
+ assert_equal 37, count, "There should be 37 fragments in the document"
45
+ end
46
+ end
47
+
48
+ def test_reverse_proxy
49
+ Net::HTTP.start("localhost", 9997) do |h|
50
+ req = h.get("/content/foo.html")
51
+ assert_not_nil req
52
+ assert_not_nil req.header
53
+ assert_not_nil req.body
54
+ assert_equal Net::HTTPOK, req.header.class
55
+ assert_match $fragment_test2, req.body, "Fragment not found"
56
+ end
57
+ end
58
+
59
+ def test_post
60
+ Net::HTTP.start("localhost","9997") do |http|
61
+ post_str = "key=value"
62
+ assert_match post_str, http.post("/post_test",post_str).read_body, "HTTP POST failed"
63
+ end
64
+ end
65
+
66
+ def test_ajax_post
67
+ Net::HTTP.start("localhost","9997") do |http|
68
+ post_str = "key=value"
69
+ post_result = http.post("/post_test", post_str,{"X-Requested-With" => "XMLHttpRequest"}).read_body
70
+ assert_match post_str, post_result, "HTTP Ajax POST failed"
71
+ end
72
+ end
73
+
74
+ def test_post_redirect
75
+ Net::HTTP.start("localhost","9997") do |http|
76
+ post_str = "key=value"
77
+ res = http.post("/post_redirect_test", post_str)
78
+ assert_equal Net::HTTPFound, res.class
79
+ assert_equal "/esi_test_content.html", res["Location"]
80
+ end
81
+ end
82
+
83
+ def test_get_redirect
84
+ Net::HTTP.start("localhost","9997") do |http|
85
+ res = http.get("/post_redirect_test")
86
+ assert_equal Net::HTTPFound, res.class
87
+ assert_equal "/esi_test_content.html", res["Location"]
88
+ end
89
+ end
90
+
91
+ # test that we're including http headers as part of the request fragment cache
92
+ def test_ajax_caching
93
+ # start by making the request using the X-Requested-With Header
94
+ Net::HTTP.start("localhost", 9997) do |h|
95
+ req = h.get("/content/ajax_test_page.html", {"X-Requested-With" => "XMLHttpRequest"})
96
+ assert_not_nil req
97
+ assert_not_nil req.header
98
+ assert_not_nil req.body
99
+ assert_equal Net::HTTPOK, req.header.class
100
+ assert_match "XMLHttpRequest", req.body, "Did not get the expected response for Javascript, should see XMLHttpRequest in the response"
101
+ end
102
+ # now the content should be cached so make the request again without the javascript header to get the alternate version
103
+ Net::HTTP.start("localhost", 9997) do |h|
104
+ req = h.get("/content/ajax_test_page.html")
105
+ assert_not_nil req
106
+ assert_not_nil req.header
107
+ assert_not_nil req.body
108
+ assert_equal Net::HTTPOK, req.header.class
109
+ assert_match "HTTP Request", req.body, "Did not get the expected response for noscript"
110
+ end
111
+ # make the ajax request one more time for good measure
112
+ Net::HTTP.start("localhost", 9997) do |h|
113
+ req = h.get("/content/ajax_test_page.html", {"X-Requested-With" => "XMLHttpRequest"})
114
+ assert_not_nil req
115
+ assert_not_nil req.header
116
+ assert_not_nil req.body
117
+ assert_equal Net::HTTPOK, req.header.class
118
+ assert_match "XMLHttpRequest", req.body, "Did not get the expected response for Javascript"
119
+ end
120
+ end
121
+
122
+ # test that if a fragment has a <esi include in it, that response comes back with a rendered module
123
+ def test_fragment_in_fragment
124
+ Net::HTTP.start("localhost", 9997) do |h|
125
+ req = h.get("/content/include_in_include.html")
126
+ assert_not_nil req
127
+ assert_not_nil req.header
128
+ assert_not_nil req.body
129
+ assert_equal Net::HTTPOK, req.header.class
130
+ assert_no_match /<esi:/, req.body, "Result still contains esi includes" # assert there are no esi tags in the result
131
+ assert_match /<div>test3<\/div>/, req.body, "assert fragment is included"
132
+ assert_match /<div>test1<\/div>/, req.body, "assert inner fragment is included"
133
+ end
134
+ end
135
+
136
+ # test whether the cache server alters the markup
137
+ def test_markup
138
+ Net::HTTP.start("localhost", 9997) do |h|
139
+ req = h.get("/content/malformed_transforms.html")
140
+ assert_not_nil req
141
+ assert_not_nil req.header
142
+ assert_not_nil req.body
143
+ assert_equal Net::HTTPOK, req.header.class
144
+ assert_equal File.open("#{DOCROOT}/content/malformed_transforms.html-correct").read, req.body
145
+ end
146
+ end
147
+
148
+ def test_failing_fragments
149
+ Net::HTTP.start("localhost", 9997) do |h|
150
+ res = h.get("/content/500.html")
151
+ assert_not_nil res
152
+ assert_not_nil res.header
153
+ assert_not_nil res.body
154
+ assert_equal Net::HTTPOK, res.header.class, res.body
155
+ end
156
+ end
157
+
158
+ def test_failing_fragments_can_failover
159
+ Net::HTTP.start("localhost", 9997) do |h|
160
+ res = h.get("/content/500_with_failover.html")
161
+ assert_not_nil res
162
+ assert_not_nil res.header
163
+ assert_not_nil res.body
164
+ assert_equal Net::HTTPOK, res.header.class, res.body
165
+ assert_match /<div>test1<\/div>/, res.body, "The failover esi include should have been requested"
166
+ end
167
+ end
168
+
169
+ def test_failing_fragments_can_failover_to_alt_attribute
170
+ Net::HTTP.start("localhost", 9997) do |h|
171
+ res = h.get("/content/500_with_failover_to_alt.html")
172
+ assert_not_nil res
173
+ assert_not_nil res.header
174
+ assert_not_nil res.body
175
+ assert_equal Net::HTTPOK, res.header.class, res.body
176
+ assert_match /<div>test1<\/div>/, res.body, "The failover esi include should have been requested"
177
+ end
178
+ end
179
+
180
+ def test_static_failover
181
+ Net::HTTP.start("localhost", 9997) do |h|
182
+ res = h.get("/content/static-failover.html")
183
+ assert_not_nil res
184
+ assert_not_nil res.header
185
+ assert_not_nil res.body
186
+ #puts res.body
187
+ assert_equal Net::HTTPOK, res.header.class, res.body
188
+ assert_match /<div>test1<\/div>/, res.body, "Normal esi include tags failed"
189
+ assert_match /<div>test1<\/div>/, res.body, "Normal esi include tags failed"
190
+ assert_match /<a href="www.akamai.com">www.example.com <\/a>/, res.body, "Static Failover failed"
191
+ end
192
+ end
193
+
194
+ def test_cookies_proxied
195
+ Net::HTTP.start("localhost", 9997) do |h|
196
+ post_str = "key=value"
197
+ req = h.post("/post_test",post_str)
198
+ assert_not_nil req
199
+ assert_not_nil req.header
200
+ assert_not_nil req.body
201
+ assert_equal Net::HTTPOK, req.header.class
202
+ assert_match TEST_COOKIE1, req.header["Set-Cookie"]
203
+ assert_match TEST_COOKIE2, req.header["Set-Cookie"]
204
+ assert_match TEST_COOKIE3, req.header["Set-Cookie"]
205
+ end
206
+ end
207
+
208
+ def test_markup_in_attempt_passed_through
209
+ Net::HTTP.start("localhost", 9997) do |h|
210
+ res = h.get("/content/test3.html")
211
+ assert_not_nil res
212
+ assert_not_nil res.header
213
+ assert_not_nil res.body
214
+ assert_equal Net::HTTPOK, res.header.class
215
+ assert_match /<p>Some markup that should not be lost<\/p>/, res.body
216
+ end
217
+ end
218
+
219
+ def test_markup_in_except_passed_through
220
+ # TODO
221
+ end
222
+
223
+ def test_surrogate_control_header
224
+ # first tell the esi handler to use the surrogate control header
225
+ $esi_dispatcher.config.config.send(:store,:enable_for_surrogate_only, true)
226
+ Net::HTTP.start("localhost", 9997) do |h|
227
+ res = h.get("/404")
228
+ assert_not_nil res
229
+ assert_not_nil res.header
230
+ assert_not_nil res.body
231
+ assert_equal Net::HTTPNotFound, res.header.class
232
+ assert_match /#{$fragment_test1}/, res.body
233
+ end
234
+ $esi_dispatcher.config.config.send(:store,:enable_for_surrogate_only, nil)
235
+
236
+ Net::HTTP.start("localhost", 9997) do |h|
237
+ res = h.get("/404-no-surrogate")
238
+ assert_not_nil res
239
+ assert_not_nil res.header
240
+ assert_not_nil res.body
241
+ assert_equal Net::HTTPNotFound, res.header.class
242
+ assert_no_match /#{$fragment_test1}/, res.body
243
+ end
244
+ end
245
+
246
+ def test_invalidation
247
+ Net::HTTP.start("localhost", 9997) do |h|
248
+ res = h.get("/esi_test_content.html")
249
+ assert_not_nil res
250
+ assert_not_nil res.header
251
+ assert_not_nil res.body
252
+ assert_equal Net::HTTPOK, res.header.class
253
+ assert_match $fragment_test1, res.body, "Fragment not found"
254
+ assert_match $fragment_test2, res.body, "Fragment not found"
255
+ end
256
+
257
+ assert cached?( FRAGMENT_TEST1_URI ), "Error Fragment should be cached!"
258
+ assert cached?( FRAGMENT_TEST2_URI ), "Error Fragment should be cached!"
259
+
260
+ Net::HTTP.start("localhost", 9997) do |h|
261
+ res = h.get("/esi_invalidate.html")
262
+ end
263
+
264
+ assert !cached?( FRAGMENT_TEST1_URI ), "Error Fragment 1 should not be cached!"
265
+ assert !cached?( FRAGMENT_TEST2_URI ), "Error Fragment 2 should not be cached!"
266
+ end
267
+
268
+
269
+ end
270
+
@@ -0,0 +1,234 @@
1
+ # modified version from mongrel
2
+ # This code is moving into integration test folder
3
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib")
4
+ $:.unshift File.join(File.dirname(__FILE__), "..", "..", "ext")
5
+ require 'esi/dispatcher'
6
+ require 'test/unit'
7
+ SERVER_ROOT = "#{File.dirname(__FILE__)}/../../"
8
+ ENV["test"] = "true"
9
+ DOCROOT = "#{File.dirname(__FILE__)}/docs/"
10
+
11
+ # Either takes a string to do a get request against, or a tuple of [URI, HTTP] where
12
+ # HTTP is some kind of Net::HTTP request object (POST, HEAD, etc.)
13
+ def hit(uris)
14
+ results = []
15
+ uris.each do |u|
16
+ res = nil
17
+
18
+ assert_nothing_raised do
19
+ if u.kind_of? String
20
+ res = Net::HTTP.get(URI.parse(u))
21
+ else
22
+ url = URI.parse(u[0])
23
+ res = Net::HTTP.new(url.host, url.port).start {|h| h.request(u[1]) }
24
+ end
25
+ end
26
+
27
+ assert_not_nil res, "Didn't get a response: #{u}"
28
+ results << res
29
+ end
30
+
31
+ return results
32
+ end
33
+
34
+ def check_status(results, expecting)
35
+ results.each do |res|
36
+ assert(res.kind_of?(expecting), "Didn't get #{expecting}, got: #{res.class}")
37
+ end
38
+ end
39
+
40
+
41
+ class MockRequest
42
+ def initialize(params={})
43
+ @params = params
44
+ end
45
+ def params
46
+ @params
47
+ end
48
+ end
49
+
50
+ def cached?( uri )
51
+ $esi_dispatcher.config.cache.get( uri, {} )
52
+ end
53
+
54
+ require 'singleton'
55
+
56
+ TEST_COOKIE1 = "s_cc=true; s_sq=%5B%5BB%5D%5D; _session_id=367df8904d23ee48ddac56012b9d509f;".freeze
57
+ TEST_COOKIE2 = "rhg_gsid=83d7e46425b431c6651e2beb3e4fd9e41175970072%3A; cookies_enabled=true;".freeze
58
+ TEST_COOKIE3 = "RTOKEN=dG9kZGZAc2ltb2hlYWx0aC5jb20%3D; rhg_sa=xbSssuHwmP5rohZ0Pcu%2BmaU3bSFU%2Br1eBq4iZgTd%2BbQ%3D; edn=Z%25A16W%25E9F%25D4f%25A5%2522j%255D%25DA%2528%2585%2586; ems=%25F2%25A9%25FBlZ%2594.a%253D%250A%251F%2506%25BD%251B%25BA%25EC; av=13; s_se_sig=dG9kZGZAc2ltb2hlYWx0aC5jb20%253D; rhg_css_to_warn=1175974191515".freeze
59
+ FRAGMENT_TEST1_URI = "http://127.0.0.1:9998/fragments/test1.html".freeze
60
+ FRAGMENT_TEST2_URI = "http://127.0.0.1:9999/content/test2.html".freeze
61
+
62
+ class PostHandler < Mongrel::HttpHandler
63
+ include Mongrel::HttpHandlerPlugin
64
+ def process(request, response)
65
+ response.start(200,true) do |head,out|
66
+ head["Set-Cookie"] = TEST_COOKIE1
67
+ head["Set-Cookie"] = TEST_COOKIE2
68
+ head["Set-Cookie"] = TEST_COOKIE3
69
+ out << request.body.read
70
+ end
71
+ end
72
+ end
73
+
74
+ class PostRedirectHandler < Mongrel::HttpHandler
75
+ include Mongrel::HttpHandlerPlugin
76
+ def process(request, response)
77
+ response.start(302,true) do |head,out|
78
+ head["Location"] = "/esi_test_content.html"
79
+ out << %Q(<html><body>You are being <a href="/test1.html">redirected</a>.</body></html>)
80
+ end
81
+ end
82
+ end
83
+
84
+ class Basic404Handler < Mongrel::HttpHandler
85
+ include Mongrel::HttpHandlerPlugin
86
+ def process(request, response)
87
+ response.start(404,true) do |head,out|
88
+ head["Surrogate-Control"] = %q(max-age=0, content="ESI/1.0 ESI-INV/1.0")
89
+ out << %q(<html><body><esi:include src='/test1.html'/></body></html>)
90
+ end
91
+ end
92
+ end
93
+
94
+ class Basic404HandlerWithoutHeader < Mongrel::HttpHandler
95
+ include Mongrel::HttpHandlerPlugin
96
+ def process(request, response)
97
+ response.start(404,true) do |head,out|
98
+ #head["Surrogate-Control"] = %q(max-age=0, content="ESI/1.0 ESI-INV/1.0")
99
+ out << %q(<html><body><esi:include src='/test1.html'/></body></html>)
100
+ end
101
+ end
102
+ end
103
+
104
+ class AjaxCacheHandler < Mongrel::HttpHandler
105
+ include Mongrel::HttpHandlerPlugin
106
+ def process(request, response)
107
+ response.start(200,true) do |head,out|
108
+ # return hello if requested with
109
+ if request.params["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
110
+ out << "XMLHttpRequest Request"
111
+ else
112
+ out << "HTTP Request"
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ class InvalidateHandler < Mongrel::HttpHandler
119
+ include Mongrel::HttpHandlerPlugin
120
+ def process(request, response)
121
+ response.start(200,true) do |head,out|
122
+ head["Surrogate-Control"] = %q(max-age=0, content="ESI/1.0 ESI-INV/1.0")
123
+
124
+ out << %Q(<html><body>
125
+ <esi:invalidate output="no">
126
+ <?xml version="1.0"?>
127
+ <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd">
128
+ <INVALIDATION VERSION="WCS-1.1">
129
+ <OBJECT>
130
+ <BASICSELECTOR URI="#{FRAGMENT_TEST1_URI}"/>
131
+ <ACTION REMOVALTTL="0"/>
132
+ <INFO VALUE="invalidating fragment test 1"/>
133
+ </OBJECT>
134
+ </INVALIDATION>
135
+ </esi:invalidate>
136
+ <esi:invalidate output="no">
137
+ <?xml version="1.0"?>
138
+ <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd">
139
+ <INVALIDATION VERSION="WCS-1.1">
140
+ <OBJECT>
141
+ <BASICSELECTOR URI="#{FRAGMENT_TEST2_URI}"/>
142
+ <ACTION REMOVALTTL="0"/>
143
+ <INFO VALUE="invalidating fragment test 2"/>
144
+ </OBJECT>
145
+ </INVALIDATION>
146
+ </esi:invalidate>
147
+ </body></html>)
148
+ end
149
+ end
150
+ end
151
+
152
+ $fragment_test1 = File.open("#{DOCROOT}/test1.html").read
153
+ $fragment_test2 = File.open("#{DOCROOT}/content/test2.html").read
154
+
155
+
156
+
157
+ $esi_dispatcher = ESI::Dispatcher.new(
158
+ :host => '127.0.0.1',
159
+ :port => 9997,
160
+ :cwd => SERVER_ROOT,
161
+ :log_file => 'log/test.log',
162
+ :pid_file => 'log/test.pid',
163
+ :daemon => false,
164
+ :debug => true,
165
+ :includes => ["mongrel-esi"],
166
+ :user => nil,
167
+ :group => nil,
168
+ :prefix => '/',
169
+ :config_file => nil,
170
+ :routing => [{:host => '127.0.0.1', :port => '9999', :match_url => '^\/(content|samples|extra|get_test).*'},
171
+ {:host => '127.0.0.1', :port => '9998', :match_url => 'default'}],
172
+ :cache => 'ruby',
173
+ :cache_options => {:servers => ['localhost:11211'], :debug => false, :namespace => 'mesi', :readyonly => false},
174
+ :allowed_content_types => ['text/plain', 'text/html'],
175
+ :enable_for_surrogate_only => false,
176
+ :invalidator => false
177
+ )
178
+
179
+ # allow access to the internal parser
180
+ class ESI::Handler
181
+ attr_reader :parser
182
+ end
183
+
184
+ module ESI
185
+ class Server
186
+ include Singleton
187
+
188
+ CONFIG = [
189
+ { :host_port => { :host => '127.0.0.1', :port => 9999 },
190
+ :handlers => [
191
+ { :uri => '/', :handler => Mongrel::DirHandler.new(DOCROOT) },
192
+ { :uri => '/get_test', :handler => AjaxCacheHandler.new(DOCROOT) }
193
+ ]
194
+ },
195
+ { :host_port => { :host => '127.0.0.1', :port => 9998 },
196
+ :handlers => [
197
+ { :uri => "/", :handler => Mongrel::DirHandler.new(DOCROOT) },
198
+ { :uri => "/fragments/", :handler => Mongrel::DirHandler.new(DOCROOT) },
199
+ { :uri => '/post_test', :handler => PostHandler.new },
200
+ { :uri => '/post_redirect_test', :handler => PostRedirectHandler.new },
201
+ { :uri => '/404', :handler => Basic404Handler.new },
202
+ { :uri => '/404-no-surrogate', :handler => Basic404HandlerWithoutHeader.new },
203
+ { :uri => '/invalidate', :handler => InvalidateHandler.new }
204
+ ]
205
+ },
206
+ { :host_port => { :host => '127.0.0.1', :port => 9997 },
207
+ :handlers => [
208
+ { :uri => "/", :handler => $esi_dispatcher }
209
+ ]
210
+ }
211
+ ]
212
+
213
+ def self.start
214
+ ESI::Server.instance
215
+ end
216
+
217
+ def initialize
218
+ @servers = CONFIG.collect do|conf|
219
+ Mongrel::Configurator.new conf[:host_port] do
220
+ listener do
221
+ conf[:handlers].each do|handler|
222
+ uri handler[:uri], :handler => handler[:handler]
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ @servers.each { |server| server.run }
229
+ at_exit do
230
+ @servers.each { |server| server.stop }
231
+ end
232
+ end
233
+ end
234
+ end