tricycle-rack-contrib 0.9.0 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -7
- data/lib/rack/contrib.rb +0 -1
- data/lib/rack/contrib/jsonp.rb +1 -1
- data/lib/rack/contrib/response_cache.rb +15 -41
- data/{tricycle-rack-contrib.gemspec → rack-contrib.gemspec} +11 -12
- data/test/spec_rack_jsonp.rb +2 -2
- data/test/spec_rack_response_cache.rb +18 -36
- metadata +10 -13
- data/lib/rack/contrib/cookies.rb +0 -50
data/Rakefile
CHANGED
@@ -44,10 +44,10 @@ task :rdoc => ["RDOX"]
|
|
44
44
|
|
45
45
|
# load gemspec like github's gem builder to surface any SAFE issues.
|
46
46
|
require 'rubygems/specification'
|
47
|
-
$spec = eval(File.read('
|
47
|
+
$spec = eval(File.read('rack-contrib.gemspec'))
|
48
48
|
|
49
49
|
def package(ext='')
|
50
|
-
"pkg/
|
50
|
+
"pkg/rack-contrib-#{$spec.version}" + ext
|
51
51
|
end
|
52
52
|
|
53
53
|
desc 'Build packages'
|
@@ -60,8 +60,8 @@ end
|
|
60
60
|
|
61
61
|
directory 'pkg/'
|
62
62
|
|
63
|
-
file package('.gem') => %w[pkg/
|
64
|
-
sh "gem build
|
63
|
+
file package('.gem') => %w[pkg/ rack-contrib.gemspec] + $spec.files do |f|
|
64
|
+
sh "gem build rack-contrib.gemspec"
|
65
65
|
mv File.basename(f.name), f.name
|
66
66
|
end
|
67
67
|
|
@@ -72,14 +72,14 @@ end
|
|
72
72
|
desc 'Publish gem and tarball to rubyforge'
|
73
73
|
task 'publish:gem' => [package('.gem'), package('.tar.gz')] do |t|
|
74
74
|
sh <<-end
|
75
|
-
rubyforge add_release rack
|
76
|
-
rubyforge add_file rack
|
75
|
+
rubyforge add_release rack rack-contrib #{$spec.version} #{package('.gem')} &&
|
76
|
+
rubyforge add_file rack rack-contrib #{$spec.version} #{package('.tar.gz')}
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
# GEMSPEC ===================================================================
|
81
81
|
|
82
|
-
file '
|
82
|
+
file 'rack-contrib.gemspec' => FileList['{lib,test}/**','Rakefile', 'README.rdoc'] do |f|
|
83
83
|
# read spec file and split out manifest section
|
84
84
|
spec = File.read(f.name)
|
85
85
|
parts = spec.split(" # = MANIFEST =\n")
|
data/lib/rack/contrib.rb
CHANGED
@@ -22,7 +22,6 @@ module Rack
|
|
22
22
|
autoload :PostBodyContentTypeParser, "rack/contrib/post_body_content_type_parser"
|
23
23
|
autoload :ProcTitle, "rack/contrib/proctitle"
|
24
24
|
autoload :Profiler, "rack/contrib/profiler"
|
25
|
-
autoload :Runtime, "rack/contrib/runtime"
|
26
25
|
autoload :Sendfile, "rack/contrib/sendfile"
|
27
26
|
autoload :Signals, "rack/contrib/signals"
|
28
27
|
autoload :TimeZone, "rack/contrib/time_zone"
|
data/lib/rack/contrib/jsonp.rb
CHANGED
@@ -22,7 +22,7 @@ module Rack
|
|
22
22
|
response = pad(request.params.delete('callback'), response)
|
23
23
|
headers['Content-Length'] = response.length.to_s
|
24
24
|
end
|
25
|
-
[status, headers, response]
|
25
|
+
[status, headers, [response]]
|
26
26
|
end
|
27
27
|
|
28
28
|
# Pads the response with the appropriate callback format according to the
|
@@ -8,45 +8,23 @@ require 'rack'
|
|
8
8
|
# be served directly by a front end webserver.
|
9
9
|
class Rack::ResponseCache
|
10
10
|
# The default proc used if a block is not provided to .new
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
11
|
+
# Returns nil (ie. don't cache) if Cache-Control includes "private" directive
|
12
|
+
# It unescapes the PATH_INFO of the environment, and makes sure that it doesn't
|
13
|
+
# include '..'. If the Content-Type of the response is text/(html|css|xml),
|
14
|
+
# return a path with the appropriate extension (.html, .css, or .xml).
|
15
|
+
# If the path ends with a / and the Content-Type is text/html, change the basename
|
16
|
+
# of the path to index.html.
|
15
17
|
DEFAULT_PATH_PROC = proc do |env, res|
|
18
|
+
if res[1].include? "Cache-Control"
|
19
|
+
return if res[1]["Cache-Control"].split(',').collect{|d|d.strip}.include? "private"
|
20
|
+
end
|
16
21
|
path = Rack::Utils.unescape(env['PATH_INFO'])
|
17
|
-
|
18
|
-
|
19
|
-
"
|
20
|
-
|
21
|
-
|
22
|
-
"text/csv" => %w[csv],
|
23
|
-
"text/html" => %w[html htm],
|
24
|
-
"text/javascript" => %w[js], "application/javascript" => %w[js],
|
25
|
-
"text/plain" => %w[txt],
|
26
|
-
"text/xml" => %w[xml],
|
27
|
-
}
|
28
|
-
content_type = res[1]['Content-Type'].to_s
|
29
|
-
|
30
|
-
if !path.include?('..') and extensions = content_types[content_type]
|
31
|
-
# path doesn't include '..' and Content-Type is whitelisted
|
32
|
-
case
|
33
|
-
when path.match(/\/$/) && content_type == "text/html"
|
34
|
-
# path ends in / and Content-Type is text/html
|
35
|
-
path << "index.html"
|
36
|
-
when File.extname(path) == ""
|
37
|
-
# no extension
|
38
|
-
path << ".#{extensions.first}"
|
39
|
-
when !extensions.include?(File.extname(path)[1..-1])
|
40
|
-
# extension agrees with Content-Type
|
41
|
-
path = nil
|
42
|
-
else
|
43
|
-
# do nothing, path is alright
|
44
|
-
end
|
45
|
-
else
|
46
|
-
path = nil
|
22
|
+
if !path.include?('..') and match = /text\/((?:x|ht)ml|css)/o.match(res[1]['Content-Type'])
|
23
|
+
type = match[1]
|
24
|
+
path = "#{path}.#{type}" unless /\.#{type}\z/.match(path)
|
25
|
+
path = File.join(File.dirname(path), 'index.html') if type == 'html' and File.basename(path) == '.html'
|
26
|
+
path
|
47
27
|
end
|
48
|
-
|
49
|
-
path
|
50
28
|
end
|
51
29
|
|
52
30
|
# Initialize a new ReponseCache object with the given arguments. Arguments:
|
@@ -87,7 +65,7 @@ class Rack::ResponseCache
|
|
87
65
|
|
88
66
|
private
|
89
67
|
def cacheable?
|
90
|
-
get and !query_string and success and !no_cache
|
68
|
+
get and !query_string and success and !no_cache
|
91
69
|
end
|
92
70
|
|
93
71
|
def get
|
@@ -102,10 +80,6 @@ class Rack::ResponseCache
|
|
102
80
|
@res[0] == 200
|
103
81
|
end
|
104
82
|
|
105
|
-
def private_cache
|
106
|
-
cache_control_directives.include? 'private'
|
107
|
-
end
|
108
|
-
|
109
83
|
def no_cache
|
110
84
|
cache_control_directives.include? 'no-cache'
|
111
85
|
end
|
@@ -2,15 +2,15 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
3
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
4
|
|
5
|
-
s.name = '
|
6
|
-
s.version = '0.9.
|
7
|
-
s.date = '
|
5
|
+
s.name = 'rack-contrib'
|
6
|
+
s.version = '0.9.3'
|
7
|
+
s.date = '2009-08-06'
|
8
8
|
|
9
|
-
s.description = "Contributed Rack Middleware and Utilities
|
10
|
-
s.summary = "Contributed Rack Middleware and Utilities
|
9
|
+
s.description = "Contributed Rack Middleware and Utilities"
|
10
|
+
s.summary = "Contributed Rack Middleware and Utilities"
|
11
11
|
|
12
|
-
s.authors = ["
|
13
|
-
s.email = "
|
12
|
+
s.authors = ["rack-devel"]
|
13
|
+
s.email = "rack-devel@googlegroups.com"
|
14
14
|
|
15
15
|
# = MANIFEST =
|
16
16
|
s.files = %w[
|
@@ -23,7 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
lib/rack/contrib/bounce_favicon.rb
|
24
24
|
lib/rack/contrib/callbacks.rb
|
25
25
|
lib/rack/contrib/config.rb
|
26
|
-
lib/rack/contrib/cookies.rb
|
27
26
|
lib/rack/contrib/csshttprequest.rb
|
28
27
|
lib/rack/contrib/deflect.rb
|
29
28
|
lib/rack/contrib/etag.rb
|
@@ -44,7 +43,7 @@ Gem::Specification.new do |s|
|
|
44
43
|
lib/rack/contrib/sendfile.rb
|
45
44
|
lib/rack/contrib/signals.rb
|
46
45
|
lib/rack/contrib/time_zone.rb
|
47
|
-
|
46
|
+
rack-contrib.gemspec
|
48
47
|
test/404.html
|
49
48
|
test/Maintenance.html
|
50
49
|
test/mail_settings.rb
|
@@ -76,13 +75,13 @@ Gem::Specification.new do |s|
|
|
76
75
|
|
77
76
|
s.extra_rdoc_files = %w[README.rdoc COPYING]
|
78
77
|
s.add_dependency 'rack', '>= 0.9.1'
|
79
|
-
s.
|
78
|
+
s.add_dependency 'test-spec', '~> 0.9.0'
|
80
79
|
s.add_development_dependency 'tmail', '>= 1.2'
|
81
80
|
s.add_development_dependency 'json', '>= 1.1'
|
82
81
|
|
83
82
|
s.has_rdoc = true
|
84
|
-
s.homepage = "http://github.com/
|
85
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "
|
83
|
+
s.homepage = "http://github.com/rack/rack-contrib/"
|
84
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "rack-contrib", "--main", "README"]
|
86
85
|
s.require_paths = %w[lib]
|
87
86
|
s.rubygems_version = '1.1.1'
|
88
87
|
end
|
data/test/spec_rack_jsonp.rb
CHANGED
@@ -11,7 +11,7 @@ context "Rack::JSONP" do
|
|
11
11
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, [test_body]] }
|
12
12
|
request = Rack::MockRequest.env_for("/", :input => "foo=bar&callback=#{callback}")
|
13
13
|
body = Rack::JSONP.new(app).call(request).last
|
14
|
-
body.should.equal "#{callback}(#{test_body})"
|
14
|
+
body.join.should.equal "#{callback}(#{test_body})"
|
15
15
|
end
|
16
16
|
|
17
17
|
specify "should modify the content length to the correct value" do
|
@@ -25,7 +25,7 @@ context "Rack::JSONP" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
specify "should not change anything if no callback param is provided" do
|
28
|
-
app = lambda { |env| [200, {'Content-Type' => 'text/plain'},
|
28
|
+
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, '{"bar":"foo"}'] }
|
29
29
|
request = Rack::MockRequest.env_for("/", :input => "foo=bar")
|
30
30
|
body = Rack::JSONP.new(app).call(request).last
|
31
31
|
body.join.should.equal '{"bar":"foo"}'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'test/spec'
|
2
2
|
require 'rack/mock'
|
3
|
-
|
4
|
-
require File.join(File.dirname(__FILE__), '../lib/rack/contrib/response_cache')
|
3
|
+
require 'rack/contrib/response_cache'
|
5
4
|
require 'fileutils'
|
6
5
|
|
7
6
|
context Rack::ResponseCache do
|
@@ -36,7 +35,7 @@ context Rack::ResponseCache do
|
|
36
35
|
@cache.should.equal('/path/to/blah.html'=>@def_value, '/path/3.html'=>@def_value)
|
37
36
|
end
|
38
37
|
|
39
|
-
specify "should not
|
38
|
+
specify "should not CACHE RESults if request method is not GET" do
|
40
39
|
request(:meth=>:post)
|
41
40
|
@cache.should.equal({})
|
42
41
|
request(:meth=>:put)
|
@@ -124,44 +123,27 @@ context Rack::ResponseCache do
|
|
124
123
|
@cache.should.equal('/path with spaces.html'=>@def_value, '/path<href>.html'=>@def_value)
|
125
124
|
end
|
126
125
|
|
127
|
-
specify "should cache html
|
126
|
+
specify "should cache html, css, and xml responses by default" do
|
128
127
|
request(:path=>'/a')
|
129
128
|
@cache.should.equal('/a.html'=>@def_value)
|
129
|
+
request(:path=>'/b', :headers=>{'CT'=>'text/xml'})
|
130
|
+
@cache.should.equal('/a.html'=>@def_value, '/b.xml'=>@def_value)
|
131
|
+
request(:path=>'/c', :headers=>{'CT'=>'text/css'})
|
132
|
+
@cache.should.equal('/a.html'=>@def_value, '/b.xml'=>@def_value, '/c.css'=>@def_value)
|
130
133
|
end
|
131
134
|
|
132
|
-
|
133
|
-
:
|
134
|
-
|
135
|
-
:
|
136
|
-
|
137
|
-
:
|
138
|
-
|
139
|
-
:xhtml => %w[application/xhtml+xml],
|
140
|
-
:xml => %w[text/xml],
|
141
|
-
}.each do |extension, mime_types|
|
142
|
-
mime_types.each do |mime_type|
|
143
|
-
specify "should cache #{mime_type} responses with the extension ('#{extension}') unchanged" do
|
144
|
-
request(:path=>"/a.#{extension}", :headers=>{'CT'=>mime_type})
|
145
|
-
@cache.should.equal("/a.#{extension}"=>@def_value)
|
146
|
-
end
|
147
|
-
|
148
|
-
specify "should cache #{mime_type} responses with the relevant extension ('#{extension}') added if not already present" do
|
149
|
-
request(:path=>'/a', :headers=>{'CT'=>mime_type})
|
150
|
-
@cache.should.equal("/a.#{extension}"=>@def_value)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
specify "should cache 'text/html' responses with the extension ('htm') unchanged" do
|
156
|
-
request(:path=>"/a.htm", :headers=>{'CT'=>"text/html"})
|
157
|
-
@cache.should.equal("/a.htm"=>@def_value)
|
135
|
+
specify "should cache responses by default with the extension added if not already present" do
|
136
|
+
request(:path=>'/a.html')
|
137
|
+
@cache.should.equal('/a.html'=>@def_value)
|
138
|
+
request(:path=>'/b.xml', :headers=>{'CT'=>'text/xml'})
|
139
|
+
@cache.should.equal('/a.html'=>@def_value, '/b.xml'=>@def_value)
|
140
|
+
request(:path=>'/c.css', :headers=>{'CT'=>'text/css'})
|
141
|
+
@cache.should.equal('/a.html'=>@def_value, '/b.xml'=>@def_value, '/c.css'=>@def_value)
|
158
142
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
@cache.should.equal({})
|
164
|
-
end
|
143
|
+
|
144
|
+
specify "should not delete existing extensions" do
|
145
|
+
request(:path=>'/d.css', :headers=>{'CT'=>'text/html'})
|
146
|
+
@cache.should.equal('/d.css.html'=>@def_value)
|
165
147
|
end
|
166
148
|
|
167
149
|
specify "should cache html responses with empty basename to index.html by default" do
|
metadata
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tricycle-rack-contrib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- tricycle
|
8
7
|
- rack-devel
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
11
|
|
13
|
-
date:
|
12
|
+
date: 2009-08-06 00:00:00 -07:00
|
14
13
|
default_executable:
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
@@ -25,7 +24,7 @@ dependencies:
|
|
25
24
|
version:
|
26
25
|
- !ruby/object:Gem::Dependency
|
27
26
|
name: test-spec
|
28
|
-
type: :
|
27
|
+
type: :runtime
|
29
28
|
version_requirement:
|
30
29
|
version_requirements: !ruby/object:Gem::Requirement
|
31
30
|
requirements:
|
@@ -53,8 +52,8 @@ dependencies:
|
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: "1.1"
|
55
54
|
version:
|
56
|
-
description: Contributed Rack Middleware and Utilities
|
57
|
-
email:
|
55
|
+
description: Contributed Rack Middleware and Utilities
|
56
|
+
email: rack-devel@googlegroups.com
|
58
57
|
executables: []
|
59
58
|
|
60
59
|
extensions: []
|
@@ -72,7 +71,6 @@ files:
|
|
72
71
|
- lib/rack/contrib/bounce_favicon.rb
|
73
72
|
- lib/rack/contrib/callbacks.rb
|
74
73
|
- lib/rack/contrib/config.rb
|
75
|
-
- lib/rack/contrib/cookies.rb
|
76
74
|
- lib/rack/contrib/csshttprequest.rb
|
77
75
|
- lib/rack/contrib/deflect.rb
|
78
76
|
- lib/rack/contrib/etag.rb
|
@@ -93,7 +91,7 @@ files:
|
|
93
91
|
- lib/rack/contrib/sendfile.rb
|
94
92
|
- lib/rack/contrib/signals.rb
|
95
93
|
- lib/rack/contrib/time_zone.rb
|
96
|
-
-
|
94
|
+
- rack-contrib.gemspec
|
97
95
|
- test/404.html
|
98
96
|
- test/Maintenance.html
|
99
97
|
- test/mail_settings.rb
|
@@ -119,15 +117,14 @@ files:
|
|
119
117
|
- test/spec_rack_response_cache.rb
|
120
118
|
- test/spec_rack_sendfile.rb
|
121
119
|
has_rdoc: true
|
122
|
-
homepage: http://github.com/
|
123
|
-
licenses:
|
124
|
-
|
120
|
+
homepage: http://github.com/rack/rack-contrib/
|
121
|
+
licenses:
|
125
122
|
post_install_message:
|
126
123
|
rdoc_options:
|
127
124
|
- --line-numbers
|
128
125
|
- --inline-source
|
129
126
|
- --title
|
130
|
-
-
|
127
|
+
- rack-contrib
|
131
128
|
- --main
|
132
129
|
- README
|
133
130
|
require_paths:
|
@@ -150,7 +147,7 @@ rubyforge_project:
|
|
150
147
|
rubygems_version: 1.3.5
|
151
148
|
signing_key:
|
152
149
|
specification_version: 2
|
153
|
-
summary: Contributed Rack Middleware and Utilities
|
150
|
+
summary: Contributed Rack Middleware and Utilities
|
154
151
|
test_files:
|
155
152
|
- test/spec_rack_accept_format.rb
|
156
153
|
- test/spec_rack_backstage.rb
|
data/lib/rack/contrib/cookies.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
class Cookies
|
3
|
-
class CookieJar < Hash
|
4
|
-
def initialize(cookies)
|
5
|
-
@set_cookies = {}
|
6
|
-
@delete_cookies = {}
|
7
|
-
super()
|
8
|
-
update(cookies)
|
9
|
-
end
|
10
|
-
|
11
|
-
def [](name)
|
12
|
-
super(name.to_s)
|
13
|
-
end
|
14
|
-
|
15
|
-
def []=(key, options)
|
16
|
-
unless options.is_a?(Hash)
|
17
|
-
options = { :value => options }
|
18
|
-
end
|
19
|
-
|
20
|
-
options[:path] ||= '/'
|
21
|
-
@set_cookies[key] = options
|
22
|
-
super(key.to_s, options[:value])
|
23
|
-
end
|
24
|
-
|
25
|
-
def delete(key, options = {})
|
26
|
-
options[:path] ||= '/'
|
27
|
-
@delete_cookies[key] = options
|
28
|
-
super(key.to_s)
|
29
|
-
end
|
30
|
-
|
31
|
-
def finish!(resp)
|
32
|
-
@set_cookies.each { |k, v| resp.set_cookie(k, v) }
|
33
|
-
@delete_cookies.each { |k, v| resp.delete_cookie(k, v) }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(app)
|
38
|
-
@app = app
|
39
|
-
end
|
40
|
-
|
41
|
-
def call(env)
|
42
|
-
req = Request.new(env)
|
43
|
-
env['rack.cookies'] = cookies = CookieJar.new(req.cookies)
|
44
|
-
status, headers, body = @app.call(env)
|
45
|
-
resp = Response.new(body, status, headers)
|
46
|
-
cookies.finish!(resp)
|
47
|
-
resp.to_a
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|