rack-esi 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|