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 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")
@@ -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
@@ -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,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
- # 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.
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
- 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
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
@@ -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.join.should.equal "#{callback}(#{test_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 CACHE RESults if request method is not GET" do
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, css, and xml responses by default" do
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
- 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)
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 not delete existing extensions" do
145
- request(:path=>'/d.css', :headers=>{'CT'=>'text/html'})
146
- @cache.should.equal('/d.css.html'=>@def_value)
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.3'
7
- s.date = '2009-08-06'
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 = "rack-devel@googlegroups.com"
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.add_dependency 'test-spec', '~> 0.9.0'
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/rack/rack-contrib/"
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.3
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: 2009-08-06 00:00:00 -07:00
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: :runtime
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: rack-devel@googlegroups.com
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/rack/rack-contrib/
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