tricycle-rack-contrib 0.9.3 → 0.9.5
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 +1 -0
- data/lib/rack/contrib/cookies.rb +50 -0
- data/lib/rack/contrib/jsonp.rb +1 -1
- data/lib/rack/contrib/response_cache.rb +41 -15
- data/test/spec_rack_jsonp.rb +2 -2
- data/test/spec_rack_response_cache.rb +36 -18
- data/{rack-contrib.gemspec → tricycle-rack-contrib.gemspec} +12 -11
- metadata +13 -10
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('rack-contrib.gemspec'))
|
47
|
+
$spec = eval(File.read('tricycle-rack-contrib.gemspec'))
|
48
48
|
|
49
49
|
def package(ext='')
|
50
|
-
"pkg/rack-contrib-#{$spec.version}" + ext
|
50
|
+
"pkg/tricycle-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/ rack-contrib.gemspec] + $spec.files do |f|
|
64
|
-
sh "gem build rack-contrib.gemspec"
|
63
|
+
file package('.gem') => %w[pkg/ tricycle-rack-contrib.gemspec] + $spec.files do |f|
|
64
|
+
sh "gem build tricycle-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 rack-contrib #{$spec.version} #{package('.gem')} &&
|
76
|
-
rubyforge add_file rack rack-contrib #{$spec.version} #{package('.tar.gz')}
|
75
|
+
rubyforge add_release rack tricycle-rack-contrib #{$spec.version} #{package('.gem')} &&
|
76
|
+
rubyforge add_file rack tricycle-rack-contrib #{$spec.version} #{package('.tar.gz')}
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
# GEMSPEC ===================================================================
|
81
81
|
|
82
|
-
file 'rack-contrib.gemspec' => FileList['{lib,test}/**','Rakefile', 'README.rdoc'] do |f|
|
82
|
+
file 'tricycle-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,6 +22,7 @@ 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"
|
25
26
|
autoload :Sendfile, "rack/contrib/sendfile"
|
26
27
|
autoload :Signals, "rack/contrib/signals"
|
27
28
|
autoload :TimeZone, "rack/contrib/time_zone"
|
@@ -0,0 +1,50 @@
|
|
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
|
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,
|
25
|
+
[status, headers, response]
|
26
26
|
end
|
27
27
|
|
28
28
|
# Pads the response with the appropriate callback format according to the
|
@@ -8,23 +8,45 @@ 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
|
-
#
|
15
|
-
# If the path ends with a / and the Content-Type is text/html, change the basename
|
16
|
-
# of the path to index.html.
|
11
|
+
# Doesn't cache unless path does not contain '..', Content-Type is
|
12
|
+
# whitelisted, and path agrees with Content-Type
|
13
|
+
# Inserts appropriate extension if no extension in path
|
14
|
+
# Uses /index.html if path ends in /
|
17
15
|
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
|
21
16
|
path = Rack::Utils.unescape(env['PATH_INFO'])
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
|
18
|
+
content_types = {
|
19
|
+
"application/pdf" => %w[pdf],
|
20
|
+
"application/xhtml+xml" => %w[xhtml],
|
21
|
+
"text/css" => %w[css],
|
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
|
27
47
|
end
|
48
|
+
|
49
|
+
path
|
28
50
|
end
|
29
51
|
|
30
52
|
# Initialize a new ReponseCache object with the given arguments. Arguments:
|
@@ -65,7 +87,7 @@ class Rack::ResponseCache
|
|
65
87
|
|
66
88
|
private
|
67
89
|
def cacheable?
|
68
|
-
get and !query_string and success and !no_cache
|
90
|
+
get and !query_string and success and !no_cache and !private_cache
|
69
91
|
end
|
70
92
|
|
71
93
|
def get
|
@@ -80,6 +102,10 @@ class Rack::ResponseCache
|
|
80
102
|
@res[0] == 200
|
81
103
|
end
|
82
104
|
|
105
|
+
def private_cache
|
106
|
+
cache_control_directives.include? 'private'
|
107
|
+
end
|
108
|
+
|
83
109
|
def no_cache
|
84
110
|
cache_control_directives.include? 'no-cache'
|
85
111
|
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.
|
14
|
+
body.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'}, '{"bar":"foo"}'] }
|
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,6 +1,7 @@
|
|
1
1
|
require 'test/spec'
|
2
2
|
require 'rack/mock'
|
3
|
-
require 'rack/contrib/response_cache'
|
3
|
+
#require 'rack/contrib/response_cache'
|
4
|
+
require File.join(File.dirname(__FILE__), '../lib/rack/contrib/response_cache')
|
4
5
|
require 'fileutils'
|
5
6
|
|
6
7
|
context Rack::ResponseCache do
|
@@ -35,7 +36,7 @@ context Rack::ResponseCache do
|
|
35
36
|
@cache.should.equal('/path/to/blah.html'=>@def_value, '/path/3.html'=>@def_value)
|
36
37
|
end
|
37
38
|
|
38
|
-
specify "should not
|
39
|
+
specify "should not cache results if request method is not GET" do
|
39
40
|
request(:meth=>:post)
|
40
41
|
@cache.should.equal({})
|
41
42
|
request(:meth=>:put)
|
@@ -123,27 +124,44 @@ context Rack::ResponseCache do
|
|
123
124
|
@cache.should.equal('/path with spaces.html'=>@def_value, '/path<href>.html'=>@def_value)
|
124
125
|
end
|
125
126
|
|
126
|
-
specify "should cache html
|
127
|
+
specify "should cache html mime_type without extension at .html" do
|
127
128
|
request(:path=>'/a')
|
128
129
|
@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)
|
133
130
|
end
|
134
131
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
132
|
+
{
|
133
|
+
:css => %w[text/css],
|
134
|
+
:csv => %w[text/csv],
|
135
|
+
:html => %w[text/html],
|
136
|
+
:js => %w[text/javascript application/javascript],
|
137
|
+
:pdf => %w[application/pdf],
|
138
|
+
:txt => %w[text/plain],
|
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
|
142
153
|
end
|
143
|
-
|
144
|
-
specify "should
|
145
|
-
request(:path=>
|
146
|
-
@cache.should.equal(
|
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)
|
158
|
+
end
|
159
|
+
|
160
|
+
[:css, :xml, :xhtml, :js, :txt, :pdf, :csv].each do |extension|
|
161
|
+
specify "should not cache if extension and content-type don't agree" do
|
162
|
+
request(:path=>"/d.#{extension}", :headers=>{'CT'=>'text/html'})
|
163
|
+
@cache.should.equal({})
|
164
|
+
end
|
147
165
|
end
|
148
166
|
|
149
167
|
specify "should cache html responses with empty basename to index.html by default" do
|
@@ -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 = 'rack-contrib'
|
6
|
-
s.version = '0.9.
|
7
|
-
s.date = '
|
5
|
+
s.name = 'tricycle-rack-contrib'
|
6
|
+
s.version = '0.9.5'
|
7
|
+
s.date = '2010-01-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, including Tricycle's modifications"
|
10
|
+
s.summary = "Contributed Rack Middleware and Utilities, including Tricycle's modifications"
|
11
11
|
|
12
|
-
s.authors = ["rack-devel"]
|
13
|
-
s.email = "
|
12
|
+
s.authors = ["tricycle", "rack-devel"]
|
13
|
+
s.email = "gems@tricycledevelopments.com"
|
14
14
|
|
15
15
|
# = MANIFEST =
|
16
16
|
s.files = %w[
|
@@ -23,6 +23,7 @@ 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
|
26
27
|
lib/rack/contrib/csshttprequest.rb
|
27
28
|
lib/rack/contrib/deflect.rb
|
28
29
|
lib/rack/contrib/etag.rb
|
@@ -43,7 +44,7 @@ Gem::Specification.new do |s|
|
|
43
44
|
lib/rack/contrib/sendfile.rb
|
44
45
|
lib/rack/contrib/signals.rb
|
45
46
|
lib/rack/contrib/time_zone.rb
|
46
|
-
rack-contrib.gemspec
|
47
|
+
tricycle-rack-contrib.gemspec
|
47
48
|
test/404.html
|
48
49
|
test/Maintenance.html
|
49
50
|
test/mail_settings.rb
|
@@ -75,13 +76,13 @@ Gem::Specification.new do |s|
|
|
75
76
|
|
76
77
|
s.extra_rdoc_files = %w[README.rdoc COPYING]
|
77
78
|
s.add_dependency 'rack', '>= 0.9.1'
|
78
|
-
s.
|
79
|
+
s.add_development_dependency 'test-spec', '~> 0.9.0'
|
79
80
|
s.add_development_dependency 'tmail', '>= 1.2'
|
80
81
|
s.add_development_dependency 'json', '>= 1.1'
|
81
82
|
|
82
83
|
s.has_rdoc = true
|
83
|
-
s.homepage = "http://github.com/
|
84
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "rack-contrib", "--main", "README"]
|
84
|
+
s.homepage = "http://github.com/tricycle/rack-contrib/"
|
85
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "tricycle-rack-contrib", "--main", "README"]
|
85
86
|
s.require_paths = %w[lib]
|
86
87
|
s.rubygems_version = '1.1.1'
|
87
88
|
end
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
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.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- tricycle
|
7
8
|
- rack-devel
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date:
|
13
|
+
date: 2010-01-06 00:00:00 +11:00
|
13
14
|
default_executable:
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,7 +25,7 @@ dependencies:
|
|
24
25
|
version:
|
25
26
|
- !ruby/object:Gem::Dependency
|
26
27
|
name: test-spec
|
27
|
-
type: :
|
28
|
+
type: :development
|
28
29
|
version_requirement:
|
29
30
|
version_requirements: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
@@ -52,8 +53,8 @@ dependencies:
|
|
52
53
|
- !ruby/object:Gem::Version
|
53
54
|
version: "1.1"
|
54
55
|
version:
|
55
|
-
description: Contributed Rack Middleware and Utilities
|
56
|
-
email:
|
56
|
+
description: Contributed Rack Middleware and Utilities, including Tricycle's modifications
|
57
|
+
email: gems@tricycledevelopments.com
|
57
58
|
executables: []
|
58
59
|
|
59
60
|
extensions: []
|
@@ -71,6 +72,7 @@ files:
|
|
71
72
|
- lib/rack/contrib/bounce_favicon.rb
|
72
73
|
- lib/rack/contrib/callbacks.rb
|
73
74
|
- lib/rack/contrib/config.rb
|
75
|
+
- lib/rack/contrib/cookies.rb
|
74
76
|
- lib/rack/contrib/csshttprequest.rb
|
75
77
|
- lib/rack/contrib/deflect.rb
|
76
78
|
- lib/rack/contrib/etag.rb
|
@@ -91,7 +93,7 @@ files:
|
|
91
93
|
- lib/rack/contrib/sendfile.rb
|
92
94
|
- lib/rack/contrib/signals.rb
|
93
95
|
- lib/rack/contrib/time_zone.rb
|
94
|
-
- rack-contrib.gemspec
|
96
|
+
- tricycle-rack-contrib.gemspec
|
95
97
|
- test/404.html
|
96
98
|
- test/Maintenance.html
|
97
99
|
- test/mail_settings.rb
|
@@ -117,14 +119,15 @@ files:
|
|
117
119
|
- test/spec_rack_response_cache.rb
|
118
120
|
- test/spec_rack_sendfile.rb
|
119
121
|
has_rdoc: true
|
120
|
-
homepage: http://github.com/
|
121
|
-
licenses:
|
122
|
+
homepage: http://github.com/tricycle/rack-contrib/
|
123
|
+
licenses: []
|
124
|
+
|
122
125
|
post_install_message:
|
123
126
|
rdoc_options:
|
124
127
|
- --line-numbers
|
125
128
|
- --inline-source
|
126
129
|
- --title
|
127
|
-
- rack-contrib
|
130
|
+
- tricycle-rack-contrib
|
128
131
|
- --main
|
129
132
|
- README
|
130
133
|
require_paths:
|
@@ -147,7 +150,7 @@ rubyforge_project:
|
|
147
150
|
rubygems_version: 1.3.5
|
148
151
|
signing_key:
|
149
152
|
specification_version: 2
|
150
|
-
summary: Contributed Rack Middleware and Utilities
|
153
|
+
summary: Contributed Rack Middleware and Utilities, including Tricycle's modifications
|
151
154
|
test_files:
|
152
155
|
- test/spec_rack_accept_format.rb
|
153
156
|
- test/spec_rack_backstage.rb
|