joshbuddy-esi-for-rack 0.0.2 → 0.0.3
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/VERSION +1 -1
- data/lib/esi_for_rack.rb +22 -24
- data/lib/esi_for_rack/lookup.rb +25 -13
- data/lib/esi_for_rack/node.rb +44 -22
- data/spec/http_integration/cookie_spec.rb +1 -1
- data/spec/http_integration/query_string_spec.rb +1 -1
- data/spec/http_integration/user_agent_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -2
- data/spec/tags/include_spec.rb +3 -3
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/lib/esi_for_rack.rb
CHANGED
@@ -14,18 +14,28 @@ class EsiForRack
|
|
14
14
|
@lookup = lookup
|
15
15
|
end
|
16
16
|
|
17
|
+
def self.response_body_to_str(response_body)
|
18
|
+
if response_body.respond_to? :to_str
|
19
|
+
response_body.to_str
|
20
|
+
elsif response_body.respond_to?(:each)
|
21
|
+
body = ''
|
22
|
+
response_body.each { |part|
|
23
|
+
body << part.to_s
|
24
|
+
}
|
25
|
+
body
|
26
|
+
else
|
27
|
+
raise TypeError, "stringable or iterable required"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
17
31
|
def call(env)
|
18
|
-
@lookup ||= Lookup::PassThrough.new(@app, env)
|
19
|
-
|
32
|
+
@lookup ||= [Lookup::PassThrough.new(@app, env), Lookup::Http.new(@app, env)]
|
20
33
|
request = Rack::Request.new(env)
|
21
34
|
result = @app.call(env)
|
22
35
|
response = Rack::Response.new(result[2], result[0], result[1])
|
23
36
|
|
24
37
|
if response['Content-Type'] =~ /text\/html/
|
25
|
-
body =
|
26
|
-
response.body.each do |part|
|
27
|
-
body << part
|
28
|
-
end
|
38
|
+
body = EsiForRack.response_body_to_str(result.last)
|
29
39
|
|
30
40
|
user_agent_hash = {}
|
31
41
|
begin
|
@@ -48,10 +58,8 @@ class EsiForRack
|
|
48
58
|
# error parsing ua
|
49
59
|
end
|
50
60
|
|
51
|
-
|
52
|
-
|
53
61
|
binding = {
|
54
|
-
:HTTP_ACCEPT_LANGUAGE => Set.new((env['HTTP_ACCEPT_LANGUAGE'] || '').split(',').map{|l| l.
|
62
|
+
:HTTP_ACCEPT_LANGUAGE => Set.new((env['HTTP_ACCEPT_LANGUAGE'] || '').split(',').map{|l| l.gsub(/q=[0-9]\.[0-9]{1,3}/, '').gsub(';','').strip}),
|
55
63
|
:HTTP_COOKIE => request.cookies,
|
56
64
|
:HTTP_HOST => request.host,
|
57
65
|
:HTTP_REFERER => request.referer,
|
@@ -59,25 +67,15 @@ class EsiForRack
|
|
59
67
|
:QUERY_STRING => request.GET
|
60
68
|
}
|
61
69
|
context = Node::Context.new(binding, @lookup)
|
62
|
-
|
70
|
+
|
71
|
+
parsed_body = context.parse(body).to_s
|
72
|
+
response.header['Content-Length'] = parsed_body.size.to_s
|
73
|
+
|
74
|
+
[response.status, response.headers, [parsed_body]]
|
63
75
|
else
|
64
76
|
result
|
65
77
|
end
|
66
78
|
|
67
79
|
end
|
68
80
|
|
69
|
-
class IOWrapper
|
70
|
-
def initialize(body)
|
71
|
-
@body = body.each
|
72
|
-
end
|
73
|
-
|
74
|
-
def read
|
75
|
-
@body.end?
|
76
|
-
end
|
77
|
-
|
78
|
-
def close
|
79
|
-
#no-op
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
81
|
end
|
data/lib/esi_for_rack/lookup.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
1
4
|
class EsiForRack
|
2
5
|
|
3
6
|
class Lookup
|
4
7
|
|
5
|
-
class
|
8
|
+
class Http
|
6
9
|
|
7
10
|
def initialize(app, env)
|
8
11
|
@app = app
|
@@ -10,6 +13,26 @@ class EsiForRack
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def [](path)
|
16
|
+
return unless path[0,4] == 'http'
|
17
|
+
uri = URI(path)
|
18
|
+
res = Net::HTTP.start(uri.host, uri.port) {|http|
|
19
|
+
http.get(uri.request_uri)
|
20
|
+
}
|
21
|
+
res.body if res.code == '200'
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class PassThrough
|
27
|
+
|
28
|
+
def initialize(app, env)
|
29
|
+
@app = app
|
30
|
+
@env = env
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](path)
|
34
|
+
return if path[0,4] == 'http'
|
35
|
+
|
13
36
|
uri = URI(path)
|
14
37
|
|
15
38
|
request = {
|
@@ -24,18 +47,7 @@ class EsiForRack
|
|
24
47
|
|
25
48
|
response = @app.call(request)
|
26
49
|
if response.first == 200
|
27
|
-
|
28
|
-
if response_body.respond_to? :to_str
|
29
|
-
response_body.to_str
|
30
|
-
elsif response_body.respond_to?(:each)
|
31
|
-
body = ''
|
32
|
-
response_body.each { |part|
|
33
|
-
body << part.to_s
|
34
|
-
}
|
35
|
-
body
|
36
|
-
else
|
37
|
-
raise TypeError, "stringable or iterable required"
|
38
|
-
end
|
50
|
+
EsiForRack.response_body_to_str(response.last)
|
39
51
|
else
|
40
52
|
nil
|
41
53
|
end
|
data/lib/esi_for_rack/node.rb
CHANGED
@@ -19,21 +19,28 @@ class EsiForRack
|
|
19
19
|
|
20
20
|
class Include < Node
|
21
21
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def resolved_src
|
23
|
+
EsiAttributeLanguage::SimpleGrammar.parse(@node['src']).execute(context.resolver)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolved_alt
|
27
|
+
EsiAttributeLanguage::SimpleGrammar.parse(@node['alt']).execute(context.resolver) if @node['alt']
|
28
|
+
end
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
def continue_on_error?
|
31
|
+
node['onerror'] == 'continue'
|
32
|
+
end
|
33
|
+
|
34
|
+
def execute
|
35
|
+
context.lookup(resolved_src) or
|
36
|
+
(resolved_alt && context.lookup(resolved_alt)) or
|
37
|
+
(!continue_on_error? && raise(IncludeFailedError.new)) or nil
|
30
38
|
end
|
31
39
|
|
32
40
|
end
|
33
41
|
|
34
42
|
class Vars < Node
|
35
|
-
def execute
|
36
|
-
#@content = node.inner_html
|
43
|
+
def execute
|
37
44
|
@content = Rack::Utils.unescape(node.inner_html)
|
38
45
|
EsiAttributeLanguage::SimpleGrammar.parse(@content).execute(context.resolver)
|
39
46
|
end
|
@@ -84,12 +91,11 @@ class EsiForRack
|
|
84
91
|
|
85
92
|
class Context
|
86
93
|
|
87
|
-
attr_reader :resolver, :
|
94
|
+
attr_reader :resolver, :doc
|
88
95
|
|
89
96
|
def initialize(resolver, lookup)
|
90
97
|
@resolver = resolver
|
91
|
-
@lookup = lookup
|
92
|
-
|
98
|
+
@lookup = lookup.is_a?(Array) ? lookup : [lookup]
|
93
99
|
@include = Include.new
|
94
100
|
@choose = Choose.new
|
95
101
|
@vars = Vars.new
|
@@ -97,6 +103,14 @@ class EsiForRack
|
|
97
103
|
|
98
104
|
end
|
99
105
|
|
106
|
+
def lookup(url)
|
107
|
+
@lookup.each do |l|
|
108
|
+
resolved_body = l[url]
|
109
|
+
return resolved_body if resolved_body
|
110
|
+
end
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
100
114
|
def parse(document)
|
101
115
|
document.gsub!('esi:', 'esi_')
|
102
116
|
|
@@ -113,19 +127,27 @@ class EsiForRack
|
|
113
127
|
|
114
128
|
def process(doc_fragment)
|
115
129
|
# have to go one at a time because of limitation of .css, its not a live list.
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
130
|
+
# ps, i'll only break if i totally have to
|
131
|
+
loop do
|
132
|
+
should_break = true
|
133
|
+
doc_fragment.css('esi_try,esi_choose,esi_vars,esi_include').each do |esi_node|
|
134
|
+
should_break = false
|
135
|
+
case esi_node.name.to_sym
|
136
|
+
when :esi_include
|
137
|
+
@include.init(esi_node, self).execute_in_place!
|
138
|
+
when :esi_choose
|
139
|
+
@choose.init(esi_node, self).execute_in_place!
|
140
|
+
when :esi_vars
|
141
|
+
@vars.init(esi_node, self).execute_in_place!
|
142
|
+
when :esi_try
|
143
|
+
@try.init(esi_node, self).execute_in_place!
|
144
|
+
break
|
145
|
+
end
|
126
146
|
end
|
147
|
+
break if should_break
|
127
148
|
end
|
128
149
|
end
|
150
|
+
|
129
151
|
end
|
130
152
|
|
131
153
|
end
|
@@ -16,7 +16,7 @@ describe "esi cookie variable lookups" do
|
|
16
16
|
|
17
17
|
request = Rack::MockRequest.env_for("/?#{Rack::Utils.build_query(vars)}")
|
18
18
|
request['HTTP_COOKIE'] = 'id=1'
|
19
|
-
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body
|
19
|
+
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\nresource\n</body></html>\n"]
|
20
20
|
|
21
21
|
end
|
22
22
|
|
@@ -15,7 +15,7 @@ describe "esi query string variable lookups" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
request = Rack::MockRequest.env_for("/?#{Rack::Utils.build_query(vars)}")
|
18
|
-
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body
|
18
|
+
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\nresource\n</body></html>\n"]
|
19
19
|
|
20
20
|
end
|
21
21
|
|
@@ -2,7 +2,7 @@ require 'spec/spec_helper'
|
|
2
2
|
|
3
3
|
describe "esi user agent variable lookups" do
|
4
4
|
|
5
|
-
it "should lookup a
|
5
|
+
it "should lookup a user agent variable" do
|
6
6
|
|
7
7
|
vars = {'type' => 'user'}
|
8
8
|
builder = Rack::Builder.new do
|
@@ -16,7 +16,7 @@ describe "esi user agent variable lookups" do
|
|
16
16
|
|
17
17
|
request = Rack::MockRequest.env_for("/?#{Rack::Utils.build_query(vars)}")
|
18
18
|
request['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2'
|
19
|
-
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\
|
19
|
+
builder.call(request).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n browserosversion\n</body></html>\n"]
|
20
20
|
|
21
21
|
end
|
22
22
|
|
data/spec/spec_helper.rb
CHANGED
data/spec/tags/include_spec.rb
CHANGED
@@ -3,11 +3,11 @@ require 'spec/spec_helper'
|
|
3
3
|
describe "esi include" do
|
4
4
|
|
5
5
|
it "should include a src" do
|
6
|
-
build_app('spec/tags/fixtures/include/src.html', {'/great' => "<p>This is great</p>"}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body
|
6
|
+
build_app('spec/tags/fixtures/include/src.html', {'/great' => "<p>This is great</p>"}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<p>This is great</p>\n</body></html>\n"]
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should include an alt if src is unavilable" do
|
10
|
-
build_app('spec/tags/fixtures/include/alt.html', {'/alternate' => "<p>This is great</p>"}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body
|
10
|
+
build_app('spec/tags/fixtures/include/alt.html', {'/alternate' => "<p>This is great</p>"}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<p>This is great</p>\n</body></html>\n"]
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should raise an error if src is unavilable" do
|
@@ -19,7 +19,7 @@ describe "esi include" do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should continue though, if onerror=continue" do
|
22
|
-
build_app('spec/tags/fixtures/include/src_continue.html', {}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body
|
22
|
+
build_app('spec/tags/fixtures/include/src_continue.html', {}).last.should == ["<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n\n</body></html>\n"]
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshbuddy-esi-for-rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-27 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- spec/tags/vars_spec.rb
|
88
88
|
has_rdoc: false
|
89
89
|
homepage: http://github.com/joshbuddy/esi_for_rack
|
90
|
+
licenses:
|
90
91
|
post_install_message:
|
91
92
|
rdoc_options:
|
92
93
|
- --charset=UTF-8
|
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
108
|
requirements: []
|
108
109
|
|
109
110
|
rubyforge_project:
|
110
|
-
rubygems_version: 1.
|
111
|
+
rubygems_version: 1.3.5
|
111
112
|
signing_key:
|
112
113
|
specification_version: 3
|
113
114
|
summary: ESI for Rack
|