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/ext/esi/parser.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require 'esi/machine'
|
|
2
|
-
|
|
3
|
-
module ESI
|
|
4
|
-
class Parser < ESI::ParserMachine
|
|
5
|
-
# Provides a stream like interface to a single parameter block
|
|
6
|
-
class StreamCallBack
|
|
7
|
-
def initialize(callback)
|
|
8
|
-
@callback = callback
|
|
9
|
-
end
|
|
10
|
-
def << (output)
|
|
11
|
-
@callback.call( output )
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
attr_accessor :esi_tag, :output, :depth
|
|
15
|
-
|
|
16
|
-
def initialize( options = {} )
|
|
17
|
-
super()
|
|
18
|
-
@data = nil
|
|
19
|
-
@prev_buffer = ""
|
|
20
|
-
@start_tag = nil # call back for when we encounter a start tag
|
|
21
|
-
@end_tag = nil # call back for when we encounter an end tag
|
|
22
|
-
@esi_tag = nil # the current active esi tag
|
|
23
|
-
@output = nil
|
|
24
|
-
@depth = options[:depth] || 0 # used to track the depth of requests include tags should be initialized with this depth
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def start_tag_handler(&block)
|
|
28
|
-
@start_tag = block
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def end_tag_handler(&block)
|
|
32
|
-
@end_tag = block
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def output_handler(&block)
|
|
36
|
-
@output = StreamCallBack.new(block)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
def stream_buffer(string)
|
|
41
|
-
if @esi_tag
|
|
42
|
-
@esi_tag.buffer( @output, string )# unless string.strip.empty?
|
|
43
|
-
else
|
|
44
|
-
@output << string
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
end
|
|
49
|
-
end
|
data/ext/esi/ruby_esi.rl
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
module ESI
|
|
2
|
-
class ParserMachine
|
|
3
|
-
|
|
4
|
-
%%{
|
|
5
|
-
machine esi;
|
|
6
|
-
|
|
7
|
-
action begin {
|
|
8
|
-
@mark = p
|
|
9
|
-
}
|
|
10
|
-
action finish {
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
# record the position of the start tag
|
|
14
|
-
action see_start_tag {
|
|
15
|
-
@tag_text = data[@mark,p-@mark]
|
|
16
|
-
@tag_info = {} # store the tag attributes
|
|
17
|
-
@tag_info[:name] = @tag_text.sub('<','').strip
|
|
18
|
-
@tag_info[:attributes] = {}
|
|
19
|
-
# puts "have esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
|
|
20
|
-
@mark = p
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
action see_end_tag {
|
|
24
|
-
# puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
|
|
25
|
-
@start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
|
|
26
|
-
@end_tag.call @tag_info[:name] if @end_tag
|
|
27
|
-
@attr_key = nil
|
|
28
|
-
@attr_value = nil
|
|
29
|
-
@tag_text = nil
|
|
30
|
-
@tag_info = nil
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
action see_block_start_with_attributes {
|
|
34
|
-
# puts "parsed esi tag at #{p}=>#{@mark}:#{data[p,1].inspect} with data #{@tag_text.inspect}"
|
|
35
|
-
@start_tag.call @tag_info[:name], @tag_info[:attributes] if @start_tag
|
|
36
|
-
@attr_key = nil
|
|
37
|
-
@attr_value = nil
|
|
38
|
-
@tag_text = nil
|
|
39
|
-
@tag_info = nil
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
action see_attribute_key {
|
|
43
|
-
@attr_key = data[@mark,p-@mark]
|
|
44
|
-
@mark += (@attr_key.size)
|
|
45
|
-
@attr_key.gsub!(/^['"]/,'')
|
|
46
|
-
@attr_key.strip!
|
|
47
|
-
# puts "SeeAttributeKey: #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect}"
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
action see_attribute_value {
|
|
51
|
-
@attr_value = data[@mark,p-@mark]
|
|
52
|
-
@attr_value.strip!
|
|
53
|
-
@attr_value.gsub!(/^=?\s*['"]/,'')
|
|
54
|
-
@attr_value.gsub!(/['"]$/,'')
|
|
55
|
-
|
|
56
|
-
@tag_info[:attributes][@attr_key] = @attr_value
|
|
57
|
-
# puts "SeeAttributeValue: #{p} #{data[@mark,1].inspect}: #{data[p,1].inspect} #{@attr_key.inspect} => #{@attr_value.inspect}"
|
|
58
|
-
@mark = p
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
action block_start_tag {
|
|
62
|
-
tag_text = data[@mark+1,p-@mark-1]
|
|
63
|
-
@start_tag.call tag_text, {} if @start_tag
|
|
64
|
-
# puts "Block start: #{p} #{tag_text}"
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
action block_end_tag {
|
|
68
|
-
tag_text = data[@mark+2,p-@mark-2]
|
|
69
|
-
@end_tag.call tag_text if @end_tag
|
|
70
|
-
# puts "Block end: #{p} #{tag_text}"
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
action echo {
|
|
74
|
-
# print " [#{data[p,1].inspect}:#{cs}] " if $debug
|
|
75
|
-
|
|
76
|
-
case cs
|
|
77
|
-
when 0
|
|
78
|
-
# NOTE: state 12 is the character state before <esi:try>, state 7 is the character before </esi:try>
|
|
79
|
-
# | |
|
|
80
|
-
# - state 12 - state 7
|
|
81
|
-
# state 60 is for empty inline tags e.g.
|
|
82
|
-
# <esi:include/>
|
|
83
|
-
# |
|
|
84
|
-
# - 60
|
|
85
|
-
|
|
86
|
-
if @prev_state != 12 and @prev_state != 7
|
|
87
|
-
if !@prev_buffer.empty? and (@prev_state != (esi_en_main + 1)) and @prev_state != 60
|
|
88
|
-
stream_buffer @prev_buffer
|
|
89
|
-
end
|
|
90
|
-
stream_buffer data[p,1]
|
|
91
|
-
end
|
|
92
|
-
@prev_buffer = ""
|
|
93
|
-
else
|
|
94
|
-
@prev_buffer << data[p,1]
|
|
95
|
-
end
|
|
96
|
-
@prev_state = cs
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
include esi_common_parser "common.rl";
|
|
100
|
-
}%%
|
|
101
|
-
|
|
102
|
-
def initialize
|
|
103
|
-
%% write data;
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# process a block of esi tags
|
|
107
|
-
def process(data)
|
|
108
|
-
if @data
|
|
109
|
-
# puts "append : #{@mark} : #{p}"
|
|
110
|
-
data = @data + data
|
|
111
|
-
p = @data.length
|
|
112
|
-
end
|
|
113
|
-
@mark ||= 0
|
|
114
|
-
p ||= 0
|
|
115
|
-
pe ||= data.length
|
|
116
|
-
@cs ||= esi_start
|
|
117
|
-
cs = @cs
|
|
118
|
-
# puts "process: #{cs.inspect} :start #{data.inspect}, #{p}"
|
|
119
|
-
%% write exec;
|
|
120
|
-
@cs = cs
|
|
121
|
-
if( @cs != esi_start && @cs != 0 )
|
|
122
|
-
# puts "append process: #{@cs.inspect}"
|
|
123
|
-
@data = data
|
|
124
|
-
else
|
|
125
|
-
@data = nil
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def finish
|
|
130
|
-
%% write eof;
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
end
|
data/lib/esi/handler.rb
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
require 'uri'
|
|
2
|
-
require 'timeout'
|
|
3
|
-
require 'net/http'
|
|
4
|
-
|
|
5
|
-
require 'esi/logger'
|
|
6
|
-
require 'esi/cache'
|
|
7
|
-
require 'esi/config'
|
|
8
|
-
require 'esi/router'
|
|
9
|
-
require 'esi/esi'
|
|
10
|
-
require 'esi/tag/base'
|
|
11
|
-
require 'esi/tag/include'
|
|
12
|
-
require 'esi/tag/invalidate'
|
|
13
|
-
require 'esi/tag/attempt'
|
|
14
|
-
require 'esi/tag/except'
|
|
15
|
-
require 'esi/tag/try'
|
|
16
|
-
|
|
17
|
-
module ESI
|
|
18
|
-
|
|
19
|
-
class Handler
|
|
20
|
-
attr_reader :config
|
|
21
|
-
include ESI::Log
|
|
22
|
-
|
|
23
|
-
def initialize(dispatcher)
|
|
24
|
-
@config = dispatcher.config
|
|
25
|
-
@router = dispatcher.router
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def process(request, response)
|
|
29
|
-
|
|
30
|
-
start = Time.now
|
|
31
|
-
status = 200
|
|
32
|
-
url = @router.url_for(request.params["REQUEST_URI"])
|
|
33
|
-
|
|
34
|
-
params = http_params(request.params)
|
|
35
|
-
|
|
36
|
-
proxy_error = nil
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
log_debug "#{request.params["REQUEST_METHOD"]} => #{url}"
|
|
40
|
-
chunk_count = 0
|
|
41
|
-
uri = URI.parse(url)
|
|
42
|
-
|
|
43
|
-
path_with_query = uri.query ? "#{uri.path}?#{uri.query}" : uri.path
|
|
44
|
-
|
|
45
|
-
proxy_request = (request.params["REQUEST_METHOD"] == "POST") ?
|
|
46
|
-
Net::HTTP::Post.new( path_with_query, params ) :
|
|
47
|
-
Net::HTTP::Get.new( path_with_query, params )
|
|
48
|
-
|
|
49
|
-
proxy_connection = Net::HTTP.start(uri.host, uri.port)
|
|
50
|
-
|
|
51
|
-
# open the conneciton up so we can start to stream the connection
|
|
52
|
-
proxy_connection.request(proxy_request,request.body.read) do|proxy_response|
|
|
53
|
-
|
|
54
|
-
status = read_status( proxy_response )
|
|
55
|
-
|
|
56
|
-
copy_headers( response.header, proxy_response ) unless status >= 500
|
|
57
|
-
|
|
58
|
-
if status >= 500 or (status < 400 and status >= 300) or !@config.enable_esi_processor?( proxy_response )
|
|
59
|
-
response.start(status, true) do|head,out|
|
|
60
|
-
|
|
61
|
-
if status >= 500
|
|
62
|
-
# TODO: only report this if configured to expose it
|
|
63
|
-
out << proxy_error
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# proxy the 500 response
|
|
67
|
-
proxy_response.read_body do|fragment|
|
|
68
|
-
out << fragment
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
end
|
|
72
|
-
else
|
|
73
|
-
# NOTE: It's very important that surrogate control headers are set to parse only if the
|
|
74
|
-
# page has esi:include tags. Because of the nature of Transfer-Encoding: chunked if we keep
|
|
75
|
-
# everything in memory until we reach an esi tag. Then we load the tag into memory and send the next
|
|
76
|
-
# chunk and so on. This means that the density of tags to markup will result in more or less of the document
|
|
77
|
-
# being stored in memory. A way we can get around this and attempt to keep a fixed size of the document in
|
|
78
|
-
# memory at all time is by setting a buffer size of say 1024. Then no matter what we'll always chunk the document
|
|
79
|
-
# by 1024 or some other size chunk.
|
|
80
|
-
begin
|
|
81
|
-
# Use the ESI Parser
|
|
82
|
-
|
|
83
|
-
response.header["Transfer-Encoding"] = "chunked"
|
|
84
|
-
# this is the important part, rather then send the whole document back we send in chunks
|
|
85
|
-
# each fragment is roughly in it's own chunk, this does mean we require http 1.1, chunk size is still a limit
|
|
86
|
-
header = Mongrel::Const::STATUS_FORMAT % [status, Mongrel::HTTP_STATUS_CODES[status]]
|
|
87
|
-
header.gsub!(/Connection: close\r\n/,'')
|
|
88
|
-
response.header.out.rewind
|
|
89
|
-
header << response.header.out.read + Mongrel::Const::LINE_END
|
|
90
|
-
header.gsub!(/Status:.*?\r\n/,'')
|
|
91
|
-
response.write( header )
|
|
92
|
-
|
|
93
|
-
#print header
|
|
94
|
-
|
|
95
|
-
parser = ESI::CParser.new
|
|
96
|
-
chunk_size = @config[:chunk_size] || 4096
|
|
97
|
-
max_depth = @config[:max_depth] || 3
|
|
98
|
-
buffer = "" # when buffer reaches chunk_size write to the response socket
|
|
99
|
-
|
|
100
|
-
# handle start tags
|
|
101
|
-
parser.start_tag_handler do|tag_name, attrs|
|
|
102
|
-
tag = ESI::Tag::Base.create( @router,
|
|
103
|
-
request.params,
|
|
104
|
-
params,
|
|
105
|
-
tag_name.gsub(/esi:/,''),
|
|
106
|
-
attrs,
|
|
107
|
-
@config.cache )
|
|
108
|
-
# set the tag depth
|
|
109
|
-
tag.depth = parser.depth if tag.respond_to?(:depth=)
|
|
110
|
-
tag.max_depth = max_depth if tag.respond_to?(:max_depth=)
|
|
111
|
-
|
|
112
|
-
if parser.esi_tag
|
|
113
|
-
parser.esi_tag.add_child(tag)
|
|
114
|
-
else
|
|
115
|
-
parser.esi_tag = tag
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# handle end tags
|
|
120
|
-
parser.end_tag_handler do|tag_name|
|
|
121
|
-
#ct = Time.now
|
|
122
|
-
if parser.esi_tag.name == tag_name.gsub(/esi:/,'')
|
|
123
|
-
parser.esi_tag.close(parser.output)
|
|
124
|
-
parser.esi_tag = nil
|
|
125
|
-
else
|
|
126
|
-
parser.esi_tag.close_child(parser.output,tag_name)
|
|
127
|
-
end
|
|
128
|
-
#puts "\t[#{tag_name}] Time to close: #{Time.now - ct}"
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# handle data streaming
|
|
132
|
-
parser.output_handler do|chars|
|
|
133
|
-
buffer << chars
|
|
134
|
-
if buffer.size >= chunk_size
|
|
135
|
-
#print buffer
|
|
136
|
-
send_chunk( response, buffer )
|
|
137
|
-
chunk_count += 1
|
|
138
|
-
buffer = ""
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
#t = Time.now
|
|
143
|
-
proxy_response.read_body do|data|
|
|
144
|
-
#pt = Time.now
|
|
145
|
-
parser.process data
|
|
146
|
-
#puts "Time in process: #{Time.now - pt}"
|
|
147
|
-
end
|
|
148
|
-
#puts "Response Time: #{Time.now - t}"
|
|
149
|
-
|
|
150
|
-
parser.finish
|
|
151
|
-
parser = nil
|
|
152
|
-
|
|
153
|
-
if buffer.size > 0
|
|
154
|
-
#print buffer
|
|
155
|
-
send_chunk( response, buffer )
|
|
156
|
-
chunk_count += 1
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
rescue => e
|
|
160
|
-
STDERR.puts "\n#{e.class}: error in #{__FILE__}:#{__LINE__}\n"
|
|
161
|
-
end
|
|
162
|
-
response.write( "0\r\n\r\n" )
|
|
163
|
-
response.done = true
|
|
164
|
-
end
|
|
165
|
-
end # end request
|
|
166
|
-
|
|
167
|
-
rescue => e
|
|
168
|
-
STDERR.puts "\n#{e.class}: error in #{__FILE__}:#{__LINE__}\n"
|
|
169
|
-
ensure
|
|
170
|
-
|
|
171
|
-
log_request "\nCompleted => #{url}, #{Time.now - start} seconds with status #{status} and #{chunk_count} chunks\n"
|
|
172
|
-
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
protected
|
|
176
|
-
|
|
177
|
-
def send_chunk( response, buffer )
|
|
178
|
-
# send a new chunk
|
|
179
|
-
size = buffer.size
|
|
180
|
-
chunk_header = "#{"%x" % size}" + Mongrel::Const::LINE_END
|
|
181
|
-
#puts chunk_header.inspect
|
|
182
|
-
response.write( chunk_header ) # write the chunk size
|
|
183
|
-
#puts buffer.inspect
|
|
184
|
-
response.write( buffer + Mongrel::Const::LINE_END ) # write the chunk
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def read_status(response)
|
|
188
|
-
Net::HTTPResponse::CODE_TO_OBJ.select { |k,v| v == response.class }.first[0].to_i rescue 500
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def http_params(params)
|
|
192
|
-
updated_params = {}
|
|
193
|
-
params.each do|k,v|
|
|
194
|
-
k = k.split('_').collect { |t| t.capitalize }.join('-')
|
|
195
|
-
if k[0,5] =='Http-'
|
|
196
|
-
k[0,5] = ''
|
|
197
|
-
updated_params[k] = v
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
updated_params
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def copy_headers(head,response)
|
|
204
|
-
response.to_hash.each do |k,v|
|
|
205
|
-
# for Set-Cookie we need to split on ,
|
|
206
|
-
# some edge cases with , since things like expires might be a date with , in them.
|
|
207
|
-
k = k.split(/-/).map{|s| s.capitalize }.join('-')
|
|
208
|
-
if k == "Set-Cookie"
|
|
209
|
-
v.each do|cookie|
|
|
210
|
-
head["Set-Cookie"] = cookie.strip # mongrel is case sensitive about handling duplicates
|
|
211
|
-
end
|
|
212
|
-
else
|
|
213
|
-
head[k] = v unless k == "Content-Length" or k == "Surrogate-Control" or k == "Server"
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
head["Server"] = "MongrelESI 0.4"
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
end # Handler
|
|
220
|
-
|
|
221
|
-
end # ESI
|
data/lib/net/ahttp.rb
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Non-blocking HTTP Client/Server Library
|
|
2
|
-
# The idea is to use Ruby 1.8.5's non blocking IO methods to provide an interface
|
|
3
|
-
# to HTTP client and server that can be more efficient then the standard Net::HTTP
|
|
4
|
-
|
|
5
|
-
module Net
|
|
6
|
-
module An
|
|
7
|
-
class HTTP
|
|
8
|
-
def self.select
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class IOSocket < Socket
|
|
13
|
-
def process
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
class IORequest < IOSocket
|
|
18
|
-
def process
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
class IOResponse < IOSocket
|
|
23
|
-
def process
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
# emits io handles, these objects have a
|
|
33
|
-
# process method
|
|
34
|
-
Net::An::HTTP.select do|io|
|
|
35
|
-
io.process
|
|
36
|
-
end
|