mongrel_esi 0.4.0
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/COPYING +53 -0
- data/LICENSE +471 -0
- data/README +186 -0
- data/Rakefile +141 -0
- data/bin/mongrel_esi +271 -0
- data/ext/esi/common.rl +41 -0
- data/ext/esi/esi_parser.c +387 -0
- data/ext/esi/extconf.rb +6 -0
- data/ext/esi/machine.rb +499 -0
- data/ext/esi/parser.c +1675 -0
- data/ext/esi/parser.h +113 -0
- data/ext/esi/parser.rb +49 -0
- data/ext/esi/parser.rl +398 -0
- data/ext/esi/ruby_esi.rl +135 -0
- data/ext/esi/run-test.rb +3 -0
- data/ext/esi/test/common.rl +41 -0
- data/ext/esi/test/parser.c +1676 -0
- data/ext/esi/test/parser.h +113 -0
- data/ext/esi/test/parser.rl +398 -0
- data/ext/esi/test/test.c +373 -0
- data/ext/esi/test1.rb +56 -0
- data/ext/esi/test2.rb +45 -0
- data/lib/esi/cache.rb +207 -0
- data/lib/esi/config.rb +154 -0
- data/lib/esi/dispatcher.rb +27 -0
- data/lib/esi/handler.rb +236 -0
- data/lib/esi/invalidator.rb +40 -0
- data/lib/esi/logger.rb +46 -0
- data/lib/esi/router.rb +84 -0
- data/lib/esi/tag/attempt.rb +6 -0
- data/lib/esi/tag/base.rb +85 -0
- data/lib/esi/tag/except.rb +24 -0
- data/lib/esi/tag/include.rb +190 -0
- data/lib/esi/tag/invalidate.rb +54 -0
- data/lib/esi/tag/try.rb +40 -0
- data/lib/multi_dirhandler.rb +70 -0
- data/setup.rb +1585 -0
- data/test/integration/basic_test.rb +39 -0
- data/test/integration/cache_test.rb +37 -0
- data/test/integration/docs/content/500.html +16 -0
- data/test/integration/docs/content/500_with_failover.html +16 -0
- data/test/integration/docs/content/500_with_failover_to_alt.html +8 -0
- data/test/integration/docs/content/ajax_test_page.html +15 -0
- data/test/integration/docs/content/cookie_variable.html +3 -0
- data/test/integration/docs/content/foo.html +15 -0
- data/test/integration/docs/content/include_in_include.html +15 -0
- data/test/integration/docs/content/malformed_transforms.html +16 -0
- data/test/integration/docs/content/malformed_transforms.html-correct +11 -0
- data/test/integration/docs/content/static-failover.html +20 -0
- data/test/integration/docs/content/test2.html +1 -0
- data/test/integration/docs/content/test3.html +17 -0
- data/test/integration/docs/esi_invalidate.html +6 -0
- data/test/integration/docs/esi_mixed_content.html +15 -0
- data/test/integration/docs/esi_test_content.html +27 -0
- data/test/integration/docs/index.html +688 -0
- data/test/integration/docs/test1.html +1 -0
- data/test/integration/docs/test3.html +9 -0
- data/test/integration/docs/test_failover.html +1 -0
- data/test/integration/handler_test.rb +270 -0
- data/test/integration/help.rb +234 -0
- data/test/net/get_test.rb +197 -0
- data/test/net/net_helper.rb +16 -0
- data/test/net/server_test.rb +249 -0
- data/test/unit/base_tag_test.rb +44 -0
- data/test/unit/esi-sample.html +56 -0
- data/test/unit/help.rb +77 -0
- data/test/unit/include_request_test.rb +69 -0
- data/test/unit/include_tag_test.rb +14 -0
- data/test/unit/parser_test.rb +478 -0
- data/test/unit/router_test.rb +34 -0
- data/test/unit/sample.html +21 -0
- data/tools/rakehelp.rb +119 -0
- metadata +182 -0
@@ -0,0 +1 @@
|
|
1
|
+
<div>test1</div>
|
@@ -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
|