mongrel_esi 0.4.1 → 0.5.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/Rakefile +15 -8
- data/bin/mongrel_esi +0 -0
- data/ext/esi/common.rl +32 -27
- data/ext/esi/esi_parser.c +11 -4
- data/ext/esi/parser.c +4536 -901
- data/ext/esi/parser.h +7 -0
- data/ext/esi/parser.rl +171 -53
- data/ext/esi/run-test.rb +0 -0
- data/ext/esi/test/common.rl +32 -27
- data/ext/esi/test/parser.c +322 -1342
- data/ext/esi/test/parser.h +7 -0
- data/ext/esi/test/parser.rl +171 -53
- data/ext/esi/test/test.c +13 -4
- data/ext/esi/test1.rb +35 -3
- data/lib/esi/cache.rb +2 -1
- data/lib/esi/config.rb +37 -0
- data/lib/esi/dispatcher.rb +3 -5
- data/lib/esi/invalidator.rb +3 -0
- data/lib/esi/logger.rb +0 -7
- data/lib/esi/parser.rb +70 -0
- data/lib/esi/processor.rb +88 -0
- data/lib/esi/proxy.rb +104 -0
- data/lib/esi/response.rb +106 -0
- data/lib/esi/router.rb +3 -0
- data/lib/esi/tag/attempt.rb +3 -0
- data/lib/esi/tag/base.rb +3 -1
- data/lib/esi/tag/except.rb +2 -0
- data/lib/esi/tag/include.rb +131 -132
- data/lib/esi/tag/invalidate.rb +2 -0
- data/lib/esi/tag/try.rb +3 -0
- data/test/integration/basic_test.rb +0 -1
- data/test/integration/docs/esi_max_age_varies.html +10 -0
- data/test/integration/handler_test.rb +31 -5
- data/test/integration/help.rb +13 -1
- data/test/load_test.rb +133 -0
- data/test/unit/include_request_test.rb +1 -1
- data/test/unit/parser_test.rb +41 -5
- data/test/unit/response_test.rb +184 -0
- metadata +50 -224
- data/doc/rdoc/classes/ESI/Cache.html +0 -178
- data/doc/rdoc/classes/ESI/Cache.src/M000060.html +0 -17
- data/doc/rdoc/classes/ESI/Cache.src/M000061.html +0 -20
- data/doc/rdoc/classes/ESI/Config/CacheConfig.html +0 -212
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000055.html +0 -19
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000056.html +0 -19
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000057.html +0 -18
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000058.html +0 -18
- data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000059.html +0 -18
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +0 -187
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000052.html +0 -19
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000053.html +0 -21
- data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000054.html +0 -21
- data/doc/rdoc/classes/ESI/Config.html +0 -291
- data/doc/rdoc/classes/ESI/Config.src/M000043.html +0 -18
- data/doc/rdoc/classes/ESI/Config.src/M000044.html +0 -18
- data/doc/rdoc/classes/ESI/Config.src/M000045.html +0 -35
- data/doc/rdoc/classes/ESI/Config.src/M000046.html +0 -38
- data/doc/rdoc/classes/ESI/Config.src/M000047.html +0 -23
- data/doc/rdoc/classes/ESI/Config.src/M000048.html +0 -18
- data/doc/rdoc/classes/ESI/Config.src/M000049.html +0 -20
- data/doc/rdoc/classes/ESI/Config.src/M000050.html +0 -18
- data/doc/rdoc/classes/ESI/Config.src/M000051.html +0 -24
- data/doc/rdoc/classes/ESI/Dispatcher.html +0 -172
- data/doc/rdoc/classes/ESI/Dispatcher.src/M000062.html +0 -23
- data/doc/rdoc/classes/ESI/Dispatcher.src/M000063.html +0 -20
- data/doc/rdoc/classes/ESI/Fragment.html +0 -218
- data/doc/rdoc/classes/ESI/Fragment.src/M000076.html +0 -21
- data/doc/rdoc/classes/ESI/Fragment.src/M000077.html +0 -18
- data/doc/rdoc/classes/ESI/Fragment.src/M000078.html +0 -18
- data/doc/rdoc/classes/ESI/Handler.html +0 -236
- data/doc/rdoc/classes/ESI/Handler.src/M000079.html +0 -19
- data/doc/rdoc/classes/ESI/Handler.src/M000080.html +0 -161
- data/doc/rdoc/classes/ESI/Handler.src/M000081.html +0 -24
- data/doc/rdoc/classes/ESI/Handler.src/M000082.html +0 -18
- data/doc/rdoc/classes/ESI/Handler.src/M000083.html +0 -26
- data/doc/rdoc/classes/ESI/Handler.src/M000084.html +0 -30
- data/doc/rdoc/classes/ESI/Invalidator.html +0 -131
- data/doc/rdoc/classes/ESI/Invalidator.src/M000004.html +0 -41
- data/doc/rdoc/classes/ESI/Log.html +0 -251
- data/doc/rdoc/classes/ESI/Log.src/M000005.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000006.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000007.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000008.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000009.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000010.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000011.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000012.html +0 -18
- data/doc/rdoc/classes/ESI/Log.src/M000013.html +0 -18
- data/doc/rdoc/classes/ESI/MemcachedCache.html +0 -314
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000034.html +0 -24
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000035.html +0 -22
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000036.html +0 -19
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000037.html +0 -23
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000038.html +0 -18
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000039.html +0 -19
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +0 -18
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +0 -18
- data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +0 -17
- data/doc/rdoc/classes/ESI/Router.html +0 -229
- data/doc/rdoc/classes/ESI/Router.src/M000073.html +0 -36
- data/doc/rdoc/classes/ESI/Router.src/M000074.html +0 -25
- data/doc/rdoc/classes/ESI/Router.src/M000075.html +0 -24
- data/doc/rdoc/classes/ESI/RubyCache.html +0 -278
- data/doc/rdoc/classes/ESI/RubyCache.src/M000064.html +0 -20
- data/doc/rdoc/classes/ESI/RubyCache.src/M000065.html +0 -22
- data/doc/rdoc/classes/ESI/RubyCache.src/M000066.html +0 -21
- data/doc/rdoc/classes/ESI/RubyCache.src/M000067.html +0 -22
- data/doc/rdoc/classes/ESI/RubyCache.src/M000068.html +0 -18
- data/doc/rdoc/classes/ESI/RubyCache.src/M000069.html +0 -22
- data/doc/rdoc/classes/ESI/RubyCache.src/M000070.html +0 -18
- data/doc/rdoc/classes/ESI/RubyCache.src/M000071.html +0 -18
- data/doc/rdoc/classes/ESI/RubyCache.src/M000072.html +0 -18
- data/doc/rdoc/classes/ESI/Tag/Attempt.html +0 -113
- data/doc/rdoc/classes/ESI/Tag/Base.html +0 -267
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000028.html +0 -26
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000029.html +0 -23
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000030.html +0 -22
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000031.html +0 -18
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000032.html +0 -22
- data/doc/rdoc/classes/ESI/Tag/Base.src/M000033.html +0 -23
- data/doc/rdoc/classes/ESI/Tag/Except.html +0 -184
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000020.html +0 -21
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000021.html +0 -20
- data/doc/rdoc/classes/ESI/Tag/Except.src/M000022.html +0 -18
- data/doc/rdoc/classes/ESI/Tag/Include.html +0 -189
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000017.html +0 -20
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000018.html +0 -18
- data/doc/rdoc/classes/ESI/Tag/Include.src/M000019.html +0 -125
- data/doc/rdoc/classes/ESI/Tag/IncludeRequest/Error.html +0 -155
- data/doc/rdoc/classes/ESI/Tag/IncludeRequest/Error.src/M000016.html +0 -19
- data/doc/rdoc/classes/ESI/Tag/IncludeRequest.html +0 -199
- data/doc/rdoc/classes/ESI/Tag/IncludeRequest.src/M000014.html +0 -18
- data/doc/rdoc/classes/ESI/Tag/IncludeRequest.src/M000015.html +0 -42
- data/doc/rdoc/classes/ESI/Tag/Invalidate.html +0 -171
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000025.html +0 -19
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000026.html +0 -51
- data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000027.html +0 -19
- data/doc/rdoc/classes/ESI/Tag/Try.html +0 -161
- data/doc/rdoc/classes/ESI/Tag/Try.src/M000023.html +0 -40
- data/doc/rdoc/classes/ESI/Tag/Try.src/M000024.html +0 -18
- data/doc/rdoc/classes/ESI/Tag.html +0 -137
- data/doc/rdoc/classes/ESI.html +0 -169
- data/doc/rdoc/classes/MultiDirHandler.html +0 -198
- data/doc/rdoc/classes/MultiDirHandler.src/M000001.html +0 -20
- data/doc/rdoc/classes/MultiDirHandler.src/M000002.html +0 -28
- data/doc/rdoc/classes/MultiDirHandler.src/M000003.html +0 -22
- data/doc/rdoc/classes/Net/An/HTTP.html +0 -137
- data/doc/rdoc/classes/Net/An/HTTP.src/M000087.html +0 -17
- data/doc/rdoc/classes/Net/An/IORequest.html +0 -139
- data/doc/rdoc/classes/Net/An/IORequest.src/M000088.html +0 -17
- data/doc/rdoc/classes/Net/An/IOResponse.html +0 -139
- data/doc/rdoc/classes/Net/An/IOResponse.src/M000085.html +0 -17
- data/doc/rdoc/classes/Net/An/IOSocket.html +0 -137
- data/doc/rdoc/classes/Net/An/IOSocket.src/M000086.html +0 -17
- data/doc/rdoc/classes/Net/An.html +0 -114
- data/doc/rdoc/classes/Net.html +0 -119
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/COPYING.html +0 -168
- data/doc/rdoc/files/LICENSE.html +0 -605
- data/doc/rdoc/files/README.html +0 -361
- data/doc/rdoc/files/lib/esi/cache_rb.html +0 -113
- data/doc/rdoc/files/lib/esi/config_rb.html +0 -108
- data/doc/rdoc/files/lib/esi/dispatcher_rb.html +0 -109
- data/doc/rdoc/files/lib/esi/handler_rb.html +0 -121
- data/doc/rdoc/files/lib/esi/invalidator_rb.html +0 -117
- data/doc/rdoc/files/lib/esi/logger_rb.html +0 -108
- data/doc/rdoc/files/lib/esi/router_rb.html +0 -101
- data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +0 -101
- data/doc/rdoc/files/lib/esi/tag/base_rb.html +0 -108
- data/doc/rdoc/files/lib/esi/tag/except_rb.html +0 -101
- data/doc/rdoc/files/lib/esi/tag/include_rb.html +0 -109
- data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +0 -109
- data/doc/rdoc/files/lib/esi/tag/try_rb.html +0 -108
- data/doc/rdoc/files/lib/multi_dirhandler_rb.html +0 -109
- data/doc/rdoc/files/lib/net/ahttp_rb.html +0 -109
- data/doc/rdoc/fr_class_index.html +0 -55
- data/doc/rdoc/fr_file_index.html +0 -44
- data/doc/rdoc/fr_method_index.html +0 -114
- data/doc/rdoc/index.html +0 -24
- data/doc/rdoc/rdoc-style.css +0 -208
- data/ext/esi/parser.rb +0 -49
- data/ext/esi/ruby_esi.rl +0 -135
- data/lib/esi/handler.rb +0 -221
- data/lib/net/ahttp.rb +0 -36
data/lib/esi/response.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'fastthread'
|
|
2
|
+
require 'thread'
|
|
3
|
+
require 'stringio'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module ESI
|
|
7
|
+
class Response
|
|
8
|
+
attr_reader :active_buffer
|
|
9
|
+
attr_accessor :output
|
|
10
|
+
|
|
11
|
+
def initialize( output )
|
|
12
|
+
@lock = Mutex.new
|
|
13
|
+
@count = 0
|
|
14
|
+
@back_buffer = []
|
|
15
|
+
@output = output
|
|
16
|
+
@last_out = -1
|
|
17
|
+
@threads = []
|
|
18
|
+
@active_buffer = reserve_buffer
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update_output(output)
|
|
22
|
+
@lock.synchronize do
|
|
23
|
+
@output = output
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def close_active_buffer
|
|
28
|
+
@lock.synchronize do
|
|
29
|
+
if !@active_buffer.closed_write?
|
|
30
|
+
@active_buffer.close_write
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def back_buffer_ready?
|
|
36
|
+
@lock.synchronize do
|
|
37
|
+
@back_buffer[@last_out+1..@count].size > 2
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def open_active_buffer
|
|
42
|
+
@lock.synchronize do
|
|
43
|
+
if @active_buffer.closed_write?
|
|
44
|
+
begin
|
|
45
|
+
@lock.unlock
|
|
46
|
+
@active_buffer = reserve_buffer
|
|
47
|
+
ensure
|
|
48
|
+
@lock.lock
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# return's new buffer
|
|
55
|
+
def reserve_buffer
|
|
56
|
+
@lock.synchronize do
|
|
57
|
+
buffer = @back_buffer[@count] = StringIO.new
|
|
58
|
+
@count += 1
|
|
59
|
+
buffer
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def send
|
|
64
|
+
@lock.synchronize do
|
|
65
|
+
# roll up requests
|
|
66
|
+
until @last_out == @count
|
|
67
|
+
o = @back_buffer[@last_out+1]
|
|
68
|
+
if o.nil? or !o.closed_write?
|
|
69
|
+
#puts "#{self} buffering...#{@last_out} to #{@count} #{@back_buffer[@last_out+1..@count].map{|b| b ? b.closed_write? : 'nil' }.join(',')}"
|
|
70
|
+
break
|
|
71
|
+
end
|
|
72
|
+
o.rewind
|
|
73
|
+
buf = o.read
|
|
74
|
+
#puts "#{Thread.current} #{self} sending: #{@last_out+1} #{buf.inspect}"
|
|
75
|
+
@back_buffer[@last_out+1] = nil # clear it out, release memory
|
|
76
|
+
@output << buf
|
|
77
|
+
@last_out += 1
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def wait_thread(thread)
|
|
83
|
+
@threads << thread
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def flush
|
|
87
|
+
@threads.each{|t| t.join }
|
|
88
|
+
@active_buffer.close_write
|
|
89
|
+
# roll up requests
|
|
90
|
+
@last_out = 0 if @last_out == -1
|
|
91
|
+
tail_buffer = (@back_buffer[@last_out..@back_buffer.size]||[])
|
|
92
|
+
#puts "\nflushing:#{Thread.current} #{self} with #{tail_buffer.inspect}"
|
|
93
|
+
while !tail_buffer.empty?
|
|
94
|
+
o = tail_buffer.shift
|
|
95
|
+
unless o.nil?
|
|
96
|
+
o.rewind
|
|
97
|
+
buf = o.read
|
|
98
|
+
#puts "#{Thread.current} #{self} flush : #{buf.inspect}"
|
|
99
|
+
@output << buf
|
|
100
|
+
end
|
|
101
|
+
#puts "#{self} sending: #{@count-tail_buffer.size}"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
data/lib/esi/router.rb
CHANGED
data/lib/esi/tag/attempt.rb
CHANGED
data/lib/esi/tag/base.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# Copyright (c) 2008 Todd A. Fisher
|
|
2
|
+
# see LICENSE
|
|
1
3
|
require 'esi/logger'
|
|
2
4
|
|
|
3
5
|
module ESI
|
|
@@ -5,7 +7,7 @@ module ESI
|
|
|
5
7
|
class Base
|
|
6
8
|
Validate = ['try','attempt','except','include','invalidate']
|
|
7
9
|
attr_reader :attributes, :children, :name, :closed, :cache
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
include ESI::Log
|
|
10
12
|
extend ESI::Log
|
|
11
13
|
|
data/lib/esi/tag/except.rb
CHANGED
data/lib/esi/tag/include.rb
CHANGED
|
@@ -1,69 +1,73 @@
|
|
|
1
|
+
# Copyright (c) 2008 Todd A. Fisher
|
|
2
|
+
# see LICENSE
|
|
1
3
|
require 'uri'
|
|
2
4
|
require 'net/http'
|
|
5
|
+
require 'esi/parser'
|
|
3
6
|
|
|
4
7
|
module ESI
|
|
5
8
|
module Tag
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
class Include < Base
|
|
10
|
+
#
|
|
11
|
+
#
|
|
12
|
+
# ir = Request.new( {'header1'=>'value1'} )
|
|
13
|
+
#
|
|
14
|
+
# ir.request( '/fragment' ) do|status,response|
|
|
15
|
+
# if status
|
|
16
|
+
# response.read_body do|str|
|
|
17
|
+
# end
|
|
18
|
+
# else
|
|
19
|
+
# # error case
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
class Request
|
|
24
|
+
class Error
|
|
25
|
+
attr_reader :message, :response
|
|
26
|
+
def initialize(msg,response)
|
|
27
|
+
@message = msg
|
|
28
|
+
@response = response
|
|
29
|
+
end
|
|
26
30
|
end
|
|
27
|
-
|
|
28
|
-
attr_reader :exception, :overflow_index # TODO
|
|
31
|
+
attr_reader :exception, :overflow_index # TODO
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
def initialize(forward_headers)
|
|
34
|
+
@headers = forward_headers
|
|
35
|
+
end
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
def request(uri, timeout = 1, alt_failover=nil, follow_limit=3)
|
|
38
|
+
uri = URI.parse(uri) if uri.is_a?(String)
|
|
39
|
+
Net::HTTP.start(uri.host, uri.port) do|http|
|
|
40
|
+
http.read_timeout = timeout if timeout and timeout > 0
|
|
41
|
+
rp = uri.query ? "#{uri.path}?#{uri.query}" : uri.path
|
|
42
|
+
http.request_get( rp, @headers ) do|response|
|
|
43
|
+
case response
|
|
44
|
+
when Net::HTTPSuccess
|
|
45
|
+
yield true, response, uri
|
|
46
|
+
when Net::HTTPRedirection
|
|
47
|
+
ir = Request.new(@headers)
|
|
48
|
+
ir.request(URI.parse(response['location']), timeout, alt_failover, follow_limit - 1) do|s,r|
|
|
49
|
+
yield s, r, URI.parse(response['location'])
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
if alt_failover
|
|
53
|
+
ir = Request.new(@headers)
|
|
54
|
+
ir.request(alt_failover, timeout, nil, follow_limit) do|s,r|
|
|
55
|
+
yield s, r, URI.parse(alt_failover)
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
yield false, Error.new("Failed to request fragment: #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}", response), uri
|
|
59
|
+
end
|
|
52
60
|
end
|
|
53
|
-
else
|
|
54
|
-
yield false, Error.new("Failed to request fragment: #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}", response), uri
|
|
55
61
|
end
|
|
56
62
|
end
|
|
63
|
+
rescue Timeout::Error => e
|
|
64
|
+
yield false, Error.new("Failed to request fragment: #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}, timeout error: #{e.message}", nil), uri
|
|
57
65
|
end
|
|
58
|
-
rescue Timeout::Error => e
|
|
59
|
-
yield false, Error.new("Failed to request fragment: #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}, timeout error: #{e.message}", nil), uri
|
|
60
|
-
end
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class Include < Base
|
|
67
|
+
end
|
|
65
68
|
|
|
66
69
|
attr_accessor :depth, :max_depth
|
|
70
|
+
|
|
67
71
|
def initialize(uri,headers,http_params,name,attrs,cache)
|
|
68
72
|
super
|
|
69
73
|
@depth = 0
|
|
@@ -76,114 +80,109 @@ module ESI
|
|
|
76
80
|
|
|
77
81
|
def close( output, options = {} )
|
|
78
82
|
super(output)
|
|
83
|
+
@output = output
|
|
79
84
|
|
|
80
|
-
raise_on_error = options[:raise] || false
|
|
81
|
-
ir = IncludeRequest.new(@http_params)
|
|
85
|
+
raise_on_error = options[:raise] || false # default to false
|
|
82
86
|
|
|
83
87
|
src = @router.url_for(prepare_url_vars(@attributes["src"]))
|
|
84
88
|
alt = @attributes['alt']
|
|
85
89
|
alt = @router.url_for(prepare_url_vars(alt)) if alt
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
prepare_parser
|
|
92
|
+
|
|
93
|
+
if @cache.cached?( src, @http_params )
|
|
94
|
+
send_from_cache( src )
|
|
95
|
+
else
|
|
96
|
+
send_from_surrogate( src, alt, raise_on_error )
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
88
100
|
|
|
101
|
+
protected
|
|
102
|
+
def prepare_parser
|
|
89
103
|
if parse_fragment?
|
|
90
|
-
parser = ESI::
|
|
91
|
-
parser.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# in esi/handler.rb
|
|
96
|
-
|
|
97
|
-
# handle start tags
|
|
98
|
-
parser.start_tag_handler do|tag_name, attrs|
|
|
99
|
-
tag = ESI::Tag::Base.create( @router,
|
|
100
|
-
@headers,
|
|
101
|
-
@http_params,
|
|
102
|
-
tag_name.gsub(/esi:/,''),
|
|
103
|
-
attrs,
|
|
104
|
-
@cache )
|
|
105
|
-
# set the tag depth
|
|
106
|
-
tag.depth = (@depth+1) if tag.respond_to?(:depth=)
|
|
107
|
-
tag.max_depth = @max_depth if tag.respond_to?(:max_depth=)
|
|
108
|
-
|
|
109
|
-
if parser.esi_tag
|
|
110
|
-
parser.esi_tag.add_child(tag)
|
|
111
|
-
else
|
|
112
|
-
parser.esi_tag = tag
|
|
104
|
+
@parser = ESI::Parser.new( @output, @router, @cache, @max_depth )
|
|
105
|
+
@parser.prepare( @headers, @http_params ) do|chars|
|
|
106
|
+
if @parser.response.active_buffer.closed_write?
|
|
107
|
+
@parser.response.open_active_buffer
|
|
108
|
+
@parser.response.send
|
|
113
109
|
end
|
|
110
|
+
@parser.response.active_buffer << chars
|
|
114
111
|
end
|
|
115
|
-
|
|
116
|
-
# handle end tags
|
|
117
|
-
parser.end_tag_handler do|tag_name|
|
|
118
|
-
if parser.esi_tag.name == tag_name.gsub(/esi:/,'')
|
|
119
|
-
parser.esi_tag.close(parser.output)
|
|
120
|
-
parser.esi_tag = nil
|
|
121
|
-
else
|
|
122
|
-
parser.esi_tag.close_child(parser.output,tag_name)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
112
|
+
@parser.depth = (@depth+1) # increment the depth
|
|
126
113
|
end
|
|
114
|
+
end
|
|
127
115
|
|
|
116
|
+
def send_from_cache( src )
|
|
117
|
+
cached_fragment = @cache.get( src, @headers ).body
|
|
118
|
+
log_request "C"
|
|
119
|
+
if parse_fragment?
|
|
128
120
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
log_request "C"
|
|
132
|
-
if parse_fragment?
|
|
133
|
-
|
|
134
|
-
parser.process cached_fragment
|
|
135
|
-
parser.finish
|
|
121
|
+
@parser.process cached_fragment
|
|
122
|
+
@parser.finish
|
|
136
123
|
|
|
137
|
-
else
|
|
138
|
-
output << cached_fragment
|
|
139
|
-
end
|
|
140
|
-
|
|
141
124
|
else
|
|
125
|
+
@output << cached_fragment
|
|
126
|
+
end
|
|
142
127
|
|
|
143
|
-
|
|
144
|
-
if status
|
|
145
|
-
# NOTE: it's important that we cache the unprocessed markup, because we need to
|
|
146
|
-
# reprocess the esi:include vars even for cached content, this way we can have cached content
|
|
147
|
-
# with HTTP_COOKIE vars and avoid re-requesting content
|
|
148
|
-
log_request "R"
|
|
149
|
-
cache_buffer = ""
|
|
150
|
-
response.read_body do|s|
|
|
151
|
-
cache_buffer << s
|
|
152
|
-
if parse_fragment?
|
|
153
|
-
parser.process s
|
|
154
|
-
else
|
|
155
|
-
output << s
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
parser.finish if parse_fragment?
|
|
128
|
+
end
|
|
160
129
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
130
|
+
def send_from_surrogate( src, alt, raise_on_error )
|
|
131
|
+
ir = Request.new(@http_params)
|
|
132
|
+
#timer = Time.now
|
|
133
|
+
ir.request(src, @attributes['timeout'].to_i, alt ) do|status,response,uri|
|
|
134
|
+
if status
|
|
135
|
+
# NOTE: it's important that we cache the unprocessed markup, because we need to
|
|
136
|
+
# reprocess the esi:include vars even for cached content, this way we can have cached content
|
|
137
|
+
# with HTTP_COOKIE vars and avoid re-requesting content
|
|
138
|
+
cache_buffer = ""
|
|
139
|
+
response.read_body do|s|
|
|
140
|
+
cache_buffer << s
|
|
141
|
+
if parse_fragment?
|
|
142
|
+
@parser.process s
|
|
167
143
|
else
|
|
168
|
-
|
|
144
|
+
@output << s
|
|
169
145
|
end
|
|
146
|
+
end
|
|
170
147
|
|
|
171
|
-
|
|
148
|
+
if parse_fragment?
|
|
149
|
+
@parser.finish
|
|
150
|
+
end
|
|
172
151
|
|
|
152
|
+
if src != uri # these won't be equal if the fragment followed a redirect or used the alt condition
|
|
153
|
+
if uri.query
|
|
154
|
+
request_uri = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}?#{uri.query}"
|
|
155
|
+
else
|
|
156
|
+
request_uri = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
|
|
157
|
+
end
|
|
173
158
|
else
|
|
174
|
-
|
|
175
|
-
return if @attributes['onerror'] == 'continue'
|
|
176
|
-
# response is an IncludeRequest::Error
|
|
177
|
-
raise response.message if raise_on_error
|
|
178
|
-
# stop processing and return the error object
|
|
179
|
-
return response
|
|
159
|
+
request_uri = src
|
|
180
160
|
end
|
|
161
|
+
|
|
162
|
+
cache_ttl = (@attributes['max-age']||600) # defaults to 600... maybe should have this be configurable?
|
|
163
|
+
if cache_ttl.respond_to?(:match) and cache_ttl.match(/\+/)
|
|
164
|
+
total=0
|
|
165
|
+
cache_ttl.split('+').each {|comp| total+=comp.to_i}
|
|
166
|
+
cache_ttl = total
|
|
167
|
+
else
|
|
168
|
+
cache_ttl = cache_ttl.to_i
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
@cache.put(request_uri, @http_params, cache_ttl, cache_buffer )
|
|
172
|
+
#log_request "R #{src} #{Time.now - timer}\n"
|
|
173
|
+
|
|
174
|
+
else
|
|
175
|
+
# error/ check if the include has an onerror specifier
|
|
176
|
+
return if @attributes['onerror'] == 'continue'
|
|
177
|
+
# response is a Request::Error
|
|
178
|
+
raise response.message if raise_on_error
|
|
179
|
+
# stop processing and return the error object
|
|
180
|
+
return response
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
|
+
end
|
|
183
184
|
|
|
184
|
-
parser = nil
|
|
185
185
|
|
|
186
|
-
end
|
|
187
186
|
end
|
|
188
187
|
|
|
189
188
|
end
|