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 CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -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.strip.gsub(/q=[0-9]\.[0-9]{1,3}/, '').gsub(';','')}),
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
- [response.status, response.headers, [context.parse(body).to_s]]
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
@@ -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 PassThrough < Lookup
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
- response_body = response.last
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
@@ -19,21 +19,28 @@ class EsiForRack
19
19
 
20
20
  class Include < Node
21
21
 
22
- def execute
23
- @resolved_src = EsiAttributeLanguage::SimpleGrammar.parse(@node['src']).execute(context.resolver)
24
- @resolved_alt = EsiAttributeLanguage::SimpleGrammar.parse(@node['alt']).execute(context.resolver) if @node['alt']
25
- @continue_on_error = node['onerror'] == 'continue'
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
- context.lookup[@resolved_src] ||
28
- (@resolved_alt && context.lookup[@resolved_alt]) ||
29
- (!@continue_on_error && raise(IncludeFailedError.new)) || nil
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, :lookup, :doc
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
- while esi_node = doc_fragment.css('esi_try,esi_choose,esi_vars,esi_include')[0]
117
- case esi_node.name.to_sym
118
- when :esi_include
119
- @include.init(esi_node, self).execute_in_place!
120
- when :esi_choose
121
- @choose.init(esi_node, self).execute_in_place!
122
- when :esi_vars
123
- @vars.init(esi_node, self).execute_in_place!
124
- when :esi_try
125
- @try.init(esi_node, self).execute_in_place!
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>resource</body></html>\n"]
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>resource</body></html>\n"]
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 cookie variable" do
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>\nbrowserosversion\n</body></html>\n"]
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
 
@@ -1,5 +1,3 @@
1
- I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 = true
2
-
3
1
  require 'rack'
4
2
  require 'lib/esi_for_rack'
5
3
 
@@ -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><p>This is great</p></body></html>\n"]
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><p>This is great</p></body></html>\n"]
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></body></html>\n"]
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.2
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-21 00:00:00 -07:00
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.2.0
111
+ rubygems_version: 1.3.5
111
112
  signing_key:
112
113
  specification_version: 3
113
114
  summary: ESI for Rack