rack-esi 0.1.2 → 0.2.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/.gitignore +4 -21
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +75 -0
- data/Rakefile +1 -53
- data/lib/rack-esi.rb +25 -77
- data/lib/rack-esi/processor.rb +55 -0
- data/lib/rack-esi/threaded.rb +50 -0
- data/lib/rack-esi/version.rb +5 -0
- data/rack-esi.gemspec +28 -0
- data/test/_test.rb +31 -0
- data/test/rack-esi_test.rb +3 -3
- data/test/teststrap.rb +7 -3
- metadata +82 -68
- data/README.markdown +0 -54
- data/VERSION +0 -1
data/.gitignore
CHANGED
@@ -1,21 +1,4 @@
|
|
1
|
-
|
2
|
-
.
|
3
|
-
|
4
|
-
|
5
|
-
*.tmproj
|
6
|
-
tmtags
|
7
|
-
|
8
|
-
## EMACS
|
9
|
-
*~
|
10
|
-
\#*
|
11
|
-
.\#*
|
12
|
-
|
13
|
-
## VIM
|
14
|
-
*.swp
|
15
|
-
|
16
|
-
## PROJECT::GENERAL
|
17
|
-
coverage
|
18
|
-
rdoc
|
19
|
-
pkg
|
20
|
-
|
21
|
-
## PROJECT::SPECIFIC
|
1
|
+
*.gem
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
pkg/*
|
data/Gemfile
ADDED
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# rack-esi
|
2
|
+
|
3
|
+
Rack-ESI is a Nokogiri based ESI middleware implementation for Rack with support for include tags, all other ESI namespaced nodes are just removed.
|
4
|
+
|
5
|
+
To make this gem work you must define the [xmlns:esi](http://www.edge-delivery.org/esi/1.0) namespace in your text/html response.
|
6
|
+
|
7
|
+
Note: This gem should only be used in development. For production use setup varnish or any other ESI enabled server.
|
8
|
+
|
9
|
+
## Features
|
10
|
+
|
11
|
+
* threaded (in case we have slow IOs)
|
12
|
+
* PATH_INFO blacklisting (:skip => nil, should respond to ===)
|
13
|
+
* support for esi|include[alt] and esi|include[noerror] fallbacks
|
14
|
+
|
15
|
+
## Dependencies
|
16
|
+
|
17
|
+
* Nokogiri
|
18
|
+
* Rack
|
19
|
+
|
20
|
+
## Setup
|
21
|
+
|
22
|
+
### w/o Gemfile
|
23
|
+
|
24
|
+
$ gem install rack-esi
|
25
|
+
|
26
|
+
### w/ Gemfile
|
27
|
+
|
28
|
+
gem 'rack-esi'
|
29
|
+
|
30
|
+
### rackup
|
31
|
+
|
32
|
+
use Rack::ESI, options || {}
|
33
|
+
run Application.new
|
34
|
+
|
35
|
+
### Rails 2.3: environment.rb
|
36
|
+
|
37
|
+
config.gem 'rack-esi' # for setups w/o Gemfile
|
38
|
+
config.middleware.unshift Rack::ESI
|
39
|
+
|
40
|
+
### Rails 3.1: application.rb
|
41
|
+
|
42
|
+
config.middleware.insert_before ActionDispatch::Static, Rack::ESI
|
43
|
+
|
44
|
+
## Options
|
45
|
+
|
46
|
+
* poolsize: 4,
|
47
|
+
Number of worker threads. A value of 1 disables threading model.
|
48
|
+
* skip: nil,
|
49
|
+
This should be an object which responds to #===(PATH_INFO).
|
50
|
+
* parser: Nokogiri::XML::Document,
|
51
|
+
You can change this to Nokogiri::HTML::Document, but you should change the serializer, too (see below).
|
52
|
+
* serializer: :to_xhtml,
|
53
|
+
The serializer value specifies the method name which is send to the object created by the parser#parse.
|
54
|
+
|
55
|
+
## TODO
|
56
|
+
|
57
|
+
* write documentation
|
58
|
+
* write more tests
|
59
|
+
* support more ESI elements
|
60
|
+
|
61
|
+
## Note on Patches/Pull Requests
|
62
|
+
|
63
|
+
* Fork the project.
|
64
|
+
* Make your feature addition or bug fix.
|
65
|
+
* Add tests for it.
|
66
|
+
* Commit, do not mess with rakefile, version, or history.
|
67
|
+
* Send me a pull request.
|
68
|
+
|
69
|
+
## Thanks
|
70
|
+
|
71
|
+
tenderlove and Qerub
|
72
|
+
|
73
|
+
## Copyright
|
74
|
+
|
75
|
+
Copyright (c) 2009 Florian Aßmann. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,53 +1 @@
|
|
1
|
-
require
|
2
|
-
require 'rake'
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'jeweler'
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = "rack-esi"
|
8
|
-
gem.summary = %Q{ESI middleware implementation for Rack.}
|
9
|
-
gem.description = %Q{Nokogiri based ESI middleware implementation for Rack with (limited) support for include, remove and comment.}
|
10
|
-
gem.email = "florian.assmann@email.de"
|
11
|
-
gem.homepage = "http://github.com/boof/rack-esi"
|
12
|
-
gem.authors = ["Florian Aßmann"]
|
13
|
-
gem.add_development_dependency "riot", ">= 0"
|
14
|
-
gem.add_development_dependency "yard", ">= 0"
|
15
|
-
gem.add_dependency 'nokogiri', '>= 0'
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
-
end
|
21
|
-
|
22
|
-
require 'rake/testtask'
|
23
|
-
Rake::TestTask.new(:test) do |test|
|
24
|
-
test.libs << 'lib' << 'test'
|
25
|
-
test.pattern = 'test/**/*_test.rb'
|
26
|
-
test.verbose = true
|
27
|
-
end
|
28
|
-
|
29
|
-
begin
|
30
|
-
require 'rcov/rcovtask'
|
31
|
-
Rcov::RcovTask.new do |test|
|
32
|
-
test.libs << 'test'
|
33
|
-
test.pattern = 'test/**/*_test.rb'
|
34
|
-
test.verbose = true
|
35
|
-
end
|
36
|
-
rescue LoadError
|
37
|
-
task :rcov do
|
38
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
task :test => :check_dependencies
|
43
|
-
|
44
|
-
task :default => :test
|
45
|
-
|
46
|
-
begin
|
47
|
-
require 'yard'
|
48
|
-
YARD::Rake::YardocTask.new
|
49
|
-
rescue LoadError
|
50
|
-
task :yardoc do
|
51
|
-
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
52
|
-
end
|
53
|
-
end
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/rack-esi.rb
CHANGED
@@ -1,97 +1,45 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.require
|
3
5
|
|
4
|
-
|
5
|
-
NS = { 'esi' => 'http://www.edge-delivery.org/esi/1.0' }
|
6
|
-
METHODS = { 'include' => :esi_include, 'remove' => nil, 'comment' => nil }
|
7
|
-
CSS = METHODS.keys.map { |cmd| "esi|#{ cmd }" } * ','
|
6
|
+
require File.expand_path('../rack-esi/processor', __FILE__)
|
8
7
|
|
9
|
-
|
10
|
-
def initialize(status, headers, response)
|
11
|
-
@status, @headers, @response = status, headers, response
|
12
|
-
end
|
13
|
-
def finish
|
14
|
-
return [@status, @headers, backtrace]
|
15
|
-
end
|
16
|
-
end
|
8
|
+
class Rack::ESI
|
17
9
|
|
18
10
|
def initialize(app, options = {})
|
19
|
-
@app
|
11
|
+
@app = app
|
20
12
|
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
13
|
+
@parser = options.fetch :parser, Nokogiri::XML::Document
|
14
|
+
@serializer = options.fetch :serializer, :to_xhtml
|
15
|
+
@skip = options[:skip]
|
16
|
+
@poolsize = options.fetch :poolsize, 4
|
17
|
+
@processor = @poolsize == 1 ? Processor::Linear : Processor::Threaded
|
25
18
|
end
|
26
19
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
return status, headers, input if skip_type? headers['Content-Type']
|
32
|
-
|
33
|
-
output = []
|
34
|
-
input.each { |body| output << compile_body(body, env, counter) }
|
35
|
-
|
36
|
-
Rack::Response.new(output, status, headers).finish
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def with_compiled_path(env, path)
|
42
|
-
# TODO: should compile variables.
|
43
|
-
env.merge 'PATH_INFO' => path, 'REQUEST_URI' => path
|
44
|
-
end
|
20
|
+
def queue(&block)
|
21
|
+
unless @queue
|
22
|
+
@queue, @group = Queue.new, ThreadGroup.new
|
23
|
+
@poolsize.times { @group.add Worker.new(@queue) }
|
45
24
|
|
46
|
-
|
47
|
-
call with_compiled_path(env, path), counter if path
|
48
|
-
rescue => e
|
49
|
-
return [500, {}, e.backtrace]
|
25
|
+
at_exit { Finisher.wait @queue }
|
50
26
|
end
|
51
27
|
|
52
|
-
|
53
|
-
|
54
|
-
document = Nokogiri.XML body
|
28
|
+
@queue.push block
|
29
|
+
end
|
55
30
|
|
56
|
-
|
57
|
-
method = METHODS[node.name] and send method, node, env, counter
|
58
|
-
node.unlink
|
59
|
-
end
|
31
|
+
attr_reader :parser, :serializer
|
60
32
|
|
61
|
-
|
62
|
-
|
33
|
+
def call(env)
|
34
|
+
return @app.call(env) if @skip === env['PATH_INFO']
|
63
35
|
|
64
|
-
|
65
|
-
@paths =~ path if @paths
|
66
|
-
end
|
67
|
-
def skip_type?(type)
|
68
|
-
@types !~ type
|
69
|
-
end
|
36
|
+
status, headers, body = @app.call env.dup
|
70
37
|
|
71
|
-
|
72
|
-
|
73
|
-
counter[:recursion] < @max_recursion
|
38
|
+
if status == 200 and headers['Content-Type'] =~ /text\/html/
|
39
|
+
body = @processor.new(self, env).process body
|
74
40
|
end
|
75
41
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
counter[:includes] += 1
|
80
|
-
counter[:recursion] += 1
|
81
|
-
|
82
|
-
status, headers, response = fetch node['src'], env, counter
|
83
|
-
status, headers, response = fetch node['alt'], env, counter if status != 200
|
84
|
-
|
85
|
-
if status == 200
|
86
|
-
data = ''
|
87
|
-
response.each { |inc| data << inc }
|
88
|
-
node.before data
|
89
|
-
elsif node['onerror'] != 'continue'
|
90
|
-
raise Error.new(status, headers, response)
|
91
|
-
end
|
92
|
-
|
93
|
-
ensure
|
94
|
-
counter[:recursion] -= 1
|
95
|
-
end
|
42
|
+
return status, headers, body
|
43
|
+
end
|
96
44
|
|
97
45
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Rack::ESI
|
2
|
+
class Processor < Struct.new(:esi, :env)
|
3
|
+
|
4
|
+
class Linear < self
|
5
|
+
def process_document(d)
|
6
|
+
d.xpath('//e:*', 'e' => NAMESPACE).each { |n| process_node n }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
autoload :Threaded, File.expand_path('../threaded', __FILE__)
|
10
|
+
|
11
|
+
NAMESPACE = 'http://www.edge-delivery.org/esi/1.0'
|
12
|
+
Error = Class.new RuntimeError
|
13
|
+
|
14
|
+
def read(enumerable, buffer = '')
|
15
|
+
enumerable.each { |str| buffer << str }
|
16
|
+
buffer
|
17
|
+
end
|
18
|
+
|
19
|
+
def include(path)
|
20
|
+
# RADAR patron here?
|
21
|
+
esi.call env.merge('PATH_INFO' => path, 'REQUEST_URI' => path)
|
22
|
+
rescue => e
|
23
|
+
return 500, {}, []
|
24
|
+
end
|
25
|
+
def process_node(node)
|
26
|
+
case node.name
|
27
|
+
when 'include'
|
28
|
+
status, headers, body = include node['src']
|
29
|
+
|
30
|
+
unless status == 200 or node['alt'].nil?
|
31
|
+
status, headers, body = include node['alt']
|
32
|
+
end
|
33
|
+
|
34
|
+
if status == 200
|
35
|
+
node.replace read(body)
|
36
|
+
elsif node['onerror'] != 'continue'
|
37
|
+
raise Error
|
38
|
+
end
|
39
|
+
else
|
40
|
+
node.remove
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def process_document(document)
|
44
|
+
raise NotImplementedError
|
45
|
+
end
|
46
|
+
def process(body)
|
47
|
+
document = esi.parser.parse read(body)
|
48
|
+
process_document document
|
49
|
+
[
|
50
|
+
document.send( esi.serializer )
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'thread'
|
2
|
+
#require 'timeout'
|
3
|
+
|
4
|
+
class Rack::ESI
|
5
|
+
|
6
|
+
class Finisher < Proc
|
7
|
+
def self.wait(queue)
|
8
|
+
finisher = new do |worker|
|
9
|
+
puts "Finishing #{ worker.inspect }..."
|
10
|
+
worker[:finish] = true
|
11
|
+
queue.push finisher
|
12
|
+
end
|
13
|
+
|
14
|
+
# cast the first stone
|
15
|
+
queue.push finisher
|
16
|
+
|
17
|
+
# wait at the end
|
18
|
+
queue.pop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Worker < Thread
|
23
|
+
def initialize(queue)
|
24
|
+
super do
|
25
|
+
begin
|
26
|
+
queue.pop[ self ]
|
27
|
+
rescue => e
|
28
|
+
puts e
|
29
|
+
end until key? :finish
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Processor::Threaded < Processor
|
35
|
+
def process_document(document)
|
36
|
+
nodes = document.xpath '//e:*', 'e' => NAMESPACE
|
37
|
+
|
38
|
+
countdown, main = nodes.length, Thread.current
|
39
|
+
nodes.each do |node|
|
40
|
+
esi.queue do
|
41
|
+
process_node node
|
42
|
+
main.run if (countdown -= 1).zero?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# TODO prevent nesting depth bigger than poolsize
|
46
|
+
Thread.stop if countdown > 0 # wait for worker
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/rack-esi.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack-esi/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-esi"
|
7
|
+
s.version = Rack::ESI::VERSION
|
8
|
+
s.authors = ["Florian Aßmann"]
|
9
|
+
s.email = ["florian.assmann@email.de"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{ ESI middleware implementation for Rack. }
|
12
|
+
s.description = <<-EOF
|
13
|
+
Rack-ESI is a Nokogiri based ESI middleware implementation for Rack with support for include tags, all other ESI namespaced nodes are just removed.
|
14
|
+
To make this gem work you must define the (xmlns:esi)[http://www.edge-delivery.org/esi/1.0] namespace in your text/html response.
|
15
|
+
Note: This gem should only be used in development. For production use setup varnish or any other ESI enabled server.
|
16
|
+
EOF
|
17
|
+
# s.rubyforge_project = "rack-esi"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
s.add_dependency "rack"
|
25
|
+
s.add_dependency "nokogiri"
|
26
|
+
# s.add_dependency "patron"
|
27
|
+
s.add_development_dependency "riot"
|
28
|
+
end
|
data/test/_test.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path('../teststrap', __FILE__)
|
2
|
+
|
3
|
+
context 'Rack::ESI' do
|
4
|
+
|
5
|
+
__dirname__ = File.expand_path File.dirname(__FILE__)
|
6
|
+
root = Pathname.new File.join(__dirname__, 'fixtures')
|
7
|
+
opts = { :urls => ['/'], :root => root }
|
8
|
+
|
9
|
+
setup { ESI.new Static.new(App.new, opts), skip: /raw/, :poolsize => 1 }
|
10
|
+
|
11
|
+
context 'GET /raw.html' do
|
12
|
+
setup { MockRequest.new(topic).get '/raw.html' }
|
13
|
+
asserts('Content-Type') { topic.content_type }.equals 'text/html'
|
14
|
+
should('not be altered') { topic.body == root.join('raw.html').read }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'GET /index.html' do
|
18
|
+
setup { MockRequest.new(topic).get '/index.html' }
|
19
|
+
|
20
|
+
asserts('Content-Type') { topic.content_type }.equals 'text/html'
|
21
|
+
should('not have any ESI specific nodes') do
|
22
|
+
html(topic.body).
|
23
|
+
at('//e:*', 'e' => Rack::ESI::Processor::NAMESPACE).nil?
|
24
|
+
end
|
25
|
+
should('have meta replacement with content') do
|
26
|
+
not html(topic.body).
|
27
|
+
at("//meta[@name='replacement' and @content='content']").nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/test/rack-esi_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'teststrap'
|
1
|
+
require File.expand_path('../teststrap', __FILE__)
|
2
2
|
|
3
3
|
context 'Rack::ESI' do
|
4
4
|
|
@@ -6,7 +6,7 @@ context 'Rack::ESI' do
|
|
6
6
|
root = Pathname.new File.join(__dirname__, 'fixtures')
|
7
7
|
opts = { :urls => ['/'], :root => root }
|
8
8
|
|
9
|
-
setup { ESI.new Static.new(App.new, opts), :
|
9
|
+
setup { ESI.new Static.new(App.new, opts), skip: /raw/, :poolsize => 1 }
|
10
10
|
|
11
11
|
context 'GET /raw.html' do
|
12
12
|
setup { MockRequest.new(topic).get '/raw.html' }
|
@@ -20,7 +20,7 @@ context 'Rack::ESI' do
|
|
20
20
|
asserts('Content-Type') { topic.content_type }.equals 'text/html'
|
21
21
|
should('not have any ESI specific nodes') do
|
22
22
|
html(topic.body).
|
23
|
-
at('//
|
23
|
+
at('//e:*', 'e' => Rack::ESI::Processor::NAMESPACE).nil?
|
24
24
|
end
|
25
25
|
should('have meta replacement with content') do
|
26
26
|
not html(topic.body).
|
data/test/teststrap.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'pathname'
|
2
|
-
require 'rubygems'
|
3
|
-
require 'riot'
|
4
|
-
require 'rack-esi'
|
5
2
|
require 'rack/mock'
|
3
|
+
require 'rack/static'
|
4
|
+
require 'rack/file'
|
5
|
+
|
6
|
+
require File.expand_path('../../lib/rack-esi', __FILE__)
|
7
|
+
Bundler.require :development
|
8
|
+
|
9
|
+
Nokogiri
|
6
10
|
|
7
11
|
def html(body)
|
8
12
|
Nokogiri.HTML(body).root
|
metadata
CHANGED
@@ -1,97 +1,111 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-esi
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
-
-
|
7
|
+
authors:
|
8
|
+
- Florian Aßmann
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: yard
|
27
|
-
type: :development
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: "0"
|
34
|
-
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-09-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: &70252059616420 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70252059616420
|
25
|
+
- !ruby/object:Gem::Dependency
|
36
26
|
name: nokogiri
|
27
|
+
requirement: &70252059615980 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
37
33
|
type: :runtime
|
38
|
-
|
39
|
-
version_requirements:
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70252059615980
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: riot
|
38
|
+
requirement: &70252059615560 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70252059615560
|
47
|
+
description: ! 'Rack-ESI is a Nokogiri based ESI middleware implementation for Rack
|
48
|
+
with support for include tags, all other ESI namespaced nodes are just removed.
|
48
49
|
|
49
|
-
|
50
|
+
To make this gem work you must define the (xmlns:esi)[http://www.edge-delivery.org/esi/1.0]
|
51
|
+
namespace in your text/html response.
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
Note: This gem should only be used in development. For production use setup varnish
|
54
|
+
or any other ESI enabled server.
|
55
|
+
|
56
|
+
'
|
57
|
+
email:
|
58
|
+
- florian.assmann@email.de
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
55
63
|
- .document
|
56
64
|
- .gitignore
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
57
67
|
- LICENSE
|
58
|
-
- README.
|
68
|
+
- README.md
|
59
69
|
- Rakefile
|
60
|
-
- VERSION
|
61
70
|
- lib/rack-esi.rb
|
71
|
+
- lib/rack-esi/processor.rb
|
72
|
+
- lib/rack-esi/threaded.rb
|
73
|
+
- lib/rack-esi/version.rb
|
74
|
+
- rack-esi.gemspec
|
75
|
+
- test/_test.rb
|
62
76
|
- test/fixtures/index.html
|
63
77
|
- test/fixtures/metatags.fragment
|
64
78
|
- test/fixtures/raw.html
|
65
79
|
- test/rack-esi_test.rb
|
66
80
|
- test/teststrap.rb
|
67
|
-
|
68
|
-
homepage: http://github.com/boof/rack-esi
|
81
|
+
homepage: ''
|
69
82
|
licenses: []
|
70
|
-
|
71
83
|
post_install_message:
|
72
|
-
rdoc_options:
|
73
|
-
|
74
|
-
require_paths:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
75
86
|
- lib
|
76
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
88
99
|
requirements: []
|
89
|
-
|
90
100
|
rubyforge_project:
|
91
|
-
rubygems_version: 1.
|
101
|
+
rubygems_version: 1.8.8
|
92
102
|
signing_key:
|
93
103
|
specification_version: 3
|
94
104
|
summary: ESI middleware implementation for Rack.
|
95
|
-
test_files:
|
105
|
+
test_files:
|
106
|
+
- test/_test.rb
|
107
|
+
- test/fixtures/index.html
|
108
|
+
- test/fixtures/metatags.fragment
|
109
|
+
- test/fixtures/raw.html
|
96
110
|
- test/rack-esi_test.rb
|
97
111
|
- test/teststrap.rb
|
data/README.markdown
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# rack-esi
|
2
|
-
|
3
|
-
Nokogiri based ESI middleware implementation for Rack with (limited) support
|
4
|
-
for include, remove and comment.
|
5
|
-
|
6
|
-
## Features
|
7
|
-
|
8
|
-
* path blacklisting (:skip => nil, expects Regexp)
|
9
|
-
* type whitelisting (:only => /^text\/(?:x|ht)ml/)
|
10
|
-
* recursion limit (:depth => 5)
|
11
|
-
* include limits (:includes => 32)
|
12
|
-
* support for <include> alt and noerror attributes
|
13
|
-
|
14
|
-
_It's for development purpose..._
|
15
|
-
|
16
|
-
## Installation
|
17
|
-
|
18
|
-
gem install rack-esi
|
19
|
-
|
20
|
-
## Rails Setup (environment.rb)
|
21
|
-
|
22
|
-
config.gem 'rack-esi'
|
23
|
-
require 'rack-esi'
|
24
|
-
config.middleware.insert_before config.middleware.first, Rack::ESI
|
25
|
-
|
26
|
-
## TODO
|
27
|
-
|
28
|
-
* write documentation
|
29
|
-
* write more tests
|
30
|
-
* support more ESI elements
|
31
|
-
* switch to Nokogiri::XML::SAX::Document?
|
32
|
-
|
33
|
-
## Dependencies
|
34
|
-
|
35
|
-
* Nokogiri
|
36
|
-
* Rack
|
37
|
-
|
38
|
-
## Note on Patches/Pull Requests
|
39
|
-
|
40
|
-
* Fork the project.
|
41
|
-
* Make your feature addition or bug fix.
|
42
|
-
* Add tests for it. This is important so I don't break it in a
|
43
|
-
future version unintentionally.
|
44
|
-
* Commit, do not mess with rakefile, version, or history.
|
45
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
46
|
-
* Send me a pull request. Bonus points for topic branches.
|
47
|
-
|
48
|
-
## Thanks
|
49
|
-
|
50
|
-
tenderlove and Qerub
|
51
|
-
|
52
|
-
## Copyright
|
53
|
-
|
54
|
-
Copyright (c) 2009 Florian Assmann. See LICENSE for details.
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.2
|