rack-contrib 1.0.1 → 1.1.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.

Potentially problematic release.


This version of rack-contrib might be problematic. Click here for more details.

@@ -26,10 +26,10 @@ interface:
26
26
  a request
27
27
  * Rack::StaticCache - Modifies the response headers to facilitiate client and proxy caching for
28
28
  static files that minimizes http requests and improves overall load times for second time visitors.
29
- * Rack::TimeZone - Detects the clients timezone using JavaScript and sets
29
+ * Rack::TimeZone - Detects the client's timezone using JavaScript and sets
30
30
  a variable in Rack's environment with the offset from UTC.
31
31
  * Rack::Evil - Lets the rack application return a response to the client from any place.
32
- * Rack::Callbacks - Implements DLS for pure before/after filter like Middlewares.
32
+ * Rack::Callbacks - Implements DSL for pure before/after filter like Middlewares.
33
33
  * Rack::Config - Shared configuration for cooperative middleware.
34
34
  * Rack::NotFound - A default 404 application.
35
35
  * Rack::CSSHTTPRequest - Adds CSSHTTPRequest support by encoding responses as
@@ -44,9 +44,10 @@ interface:
44
44
  * Rack::AcceptFormat - Adds a format extension at the end of the URI when there is none, corresponding to the mime-type given in the Accept HTTP header.
45
45
  * Rack::HostMeta - Configures /host-meta using a block
46
46
  * Rack::Cookies - Adds simple cookie jar hash to env
47
- * Rack::Access - Limit access based on IP address
48
- * Rack::ResponseHeaders - Manipulate response headers object at runtime
49
- * Rack::SimpleEndpoint - Create simple endpoints with routing rules, similar to Sinatra actions
47
+ * Rack::Access - Limits access based on IP address
48
+ * Rack::ResponseHeaders - Manipulates response headers object at runtime
49
+ * Rack::SimpleEndpoint - Creates simple endpoints with routing rules, similar to Sinatra actions
50
+ * Rack::TryStatic - Tries to match request to a static file
50
51
 
51
52
  === Use
52
53
 
@@ -0,0 +1,41 @@
1
+ module Rack
2
+ # Rack middleware to use common cookies across domain and subdomains.
3
+ class CommonCookies
4
+ DOMAIN_REGEXP = /([^.]*)\.([^.]*|..\...|...\...|..\....)$/
5
+ LOCALHOST_OR_IP_REGEXP = /^([\d.]+|localhost)$/
6
+ PORT = /:\d+$/
7
+
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ @app.call(env).tap do |(status, headers, response)|
14
+ @host = env['HTTP_HOST'].sub PORT, ''
15
+ share_cookie headers
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def domain
22
+ @domain ||= begin
23
+ @host =~ DOMAIN_REGEXP
24
+ ".#{$1}.#{$2}"
25
+ end
26
+ end
27
+
28
+ def share_cookie(headers)
29
+ headers['Set-Cookie'] &&= common_cookie(headers) if @host !~ LOCALHOST_OR_IP_REGEXP
30
+ end
31
+
32
+ def cookie(headers)
33
+ cookies = headers['Set-Cookie']
34
+ cookies.is_a?(Array) ? cookies.join("\n") : cookies
35
+ end
36
+
37
+ def common_cookie(headers)
38
+ cookie(headers).gsub(/; domain=[^;]*/, '').gsub(/$/, "; domain=#{domain}")
39
+ end
40
+ end
41
+ end
@@ -27,7 +27,7 @@ module Rack
27
27
  response = pad(request.params.delete('callback'), response)
28
28
 
29
29
  # No longer json, its javascript!
30
- headers['Content-Type'].gsub!('json', 'javascript')
30
+ headers['Content-Type'] = headers['Content-Type'].gsub('json', 'javascript')
31
31
 
32
32
  # Set new Content-Length, if it was set before we mutated the response body
33
33
  if headers['Content-Length']
@@ -41,7 +41,7 @@ module Rack
41
41
  private
42
42
 
43
43
  def is_json?(headers)
44
- headers['Content-Type'].include?('application/json')
44
+ headers.key?('Content-Type') && headers['Content-Type'].include?('application/json')
45
45
  end
46
46
 
47
47
  def has_callback?(request)
@@ -70,11 +70,23 @@ module Rack
70
70
  env['mail.sent'] = true
71
71
  return if smtp[:server] == 'example.com'
72
72
 
73
- Net::SMTP.start smtp[:server], smtp[:port], smtp[:domain], smtp[:user_name], smtp[:password], smtp[:authentication] do |server|
74
- mail.to.each do |recipient|
75
- server.send_message mail.to_s, mail.from, recipient
76
- end
73
+ server = service.new(smtp[:server], smtp[:port])
74
+
75
+ if smtp[:enable_starttls_auto] == :auto
76
+ server.enable_starttls_auto
77
+ elsif smtp[:enable_starttls_auto]
78
+ server.enable_starttls
77
79
  end
80
+
81
+ server.start smtp[:domain], smtp[:user_name], smtp[:password], smtp[:authentication]
82
+
83
+ mail.to.each do |recipient|
84
+ server.send_message mail.to_s, mail.from, recipient
85
+ end
86
+ end
87
+
88
+ def service
89
+ Net::SMTP
78
90
  end
79
91
 
80
92
  def extract_body(env)
@@ -0,0 +1,36 @@
1
+ module Rack
2
+
3
+ # The Rack::TryStatic middleware delegates requests to Rack::Static middleware
4
+ # trying to match a static file
5
+ #
6
+ # Examples
7
+ #
8
+ # use Rack::TryStatic,
9
+ # :root => "public", # static files root dir
10
+ # :urls => %w[/], # match all requests
11
+ # :try => ['.html', 'index.html', '/index.html'] # try these postfixes sequentially
12
+ #
13
+ # uses same options as Rack::Static with extra :try option which is an array
14
+ # of postfixes to find desired file
15
+
16
+ class TryStatic
17
+
18
+ def initialize(app, options)
19
+ @app = app
20
+ @try = ['', *options.delete(:try)]
21
+ @static = ::Rack::Static.new(
22
+ lambda { [404, {}, []] },
23
+ options)
24
+ end
25
+
26
+ def call(env)
27
+ orig_path = env['PATH_INFO']
28
+ found = nil
29
+ @try.each do |path|
30
+ resp = @static.call(env.merge!({'PATH_INFO' => orig_path + path}))
31
+ break if 404 != resp[0] && found = resp
32
+ end
33
+ found or @app.call(env.merge!('PATH_INFO' => orig_path))
34
+ end
35
+ end
36
+ end
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rack-contrib'
6
- s.version = '1.0.1'
7
- s.date = '2010-06-09'
6
+ s.version = '1.1.0'
7
+ s.date = '2010-10-19'
8
8
 
9
9
  s.description = "Contributed Rack Middleware and Utilities"
10
10
  s.summary = "Contributed Rack Middleware and Utilities"
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  lib/rack/contrib/backstage.rb
25
25
  lib/rack/contrib/bounce_favicon.rb
26
26
  lib/rack/contrib/callbacks.rb
27
+ lib/rack/contrib/common_cookies.rb
27
28
  lib/rack/contrib/config.rb
28
29
  lib/rack/contrib/cookies.rb
29
30
  lib/rack/contrib/csshttprequest.rb
@@ -51,15 +52,20 @@ Gem::Specification.new do |s|
51
52
  lib/rack/contrib/simple_endpoint.rb
52
53
  lib/rack/contrib/static_cache.rb
53
54
  lib/rack/contrib/time_zone.rb
55
+ lib/rack/contrib/try_static.rb
54
56
  rack-contrib.gemspec
55
57
  test/404.html
56
58
  test/Maintenance.html
59
+ test/documents/existing.html
60
+ test/documents/index.htm
61
+ test/documents/index.html
57
62
  test/documents/test
58
63
  test/mail_settings.rb
59
64
  test/spec_rack_accept_format.rb
60
65
  test/spec_rack_access.rb
61
66
  test/spec_rack_backstage.rb
62
67
  test/spec_rack_callbacks.rb
68
+ test/spec_rack_common_cookies.rb
63
69
  test/spec_rack_config.rb
64
70
  test/spec_rack_contrib.rb
65
71
  test/spec_rack_cookies.rb
@@ -84,6 +90,7 @@ Gem::Specification.new do |s|
84
90
  test/spec_rack_sendfile.rb
85
91
  test/spec_rack_simple_endpoint.rb
86
92
  test/spec_rack_static_cache.rb
93
+ test/spec_rack_try_static.rb
87
94
  test/statics/test
88
95
  ]
89
96
  # = MANIFEST =
@@ -0,0 +1 @@
1
+ existing.html
@@ -0,0 +1 @@
1
+ index.htm
@@ -0,0 +1 @@
1
+ index.html
@@ -10,3 +10,11 @@ TEST_SMTP = nil
10
10
  # :user_name => nil,
11
11
  # :password => nil
12
12
  # }
13
+ #TEST_SMTP_TLS = {
14
+ # :server => 'smtp.gmail.com',
15
+ # :domain => 'gmail.com',
16
+ # :port => 587,
17
+ # :authentication => 'plain',
18
+ # :user_name => nil,
19
+ # :password => nil,
20
+ #}
@@ -0,0 +1,107 @@
1
+ require 'test/spec'
2
+ require 'rack/mock'
3
+ require 'rack/builder'
4
+ require 'rack/contrib/common_cookies'
5
+
6
+ context Rack::CommonCookies do
7
+
8
+ setup do
9
+ @app = Rack::Builder.new do
10
+ use Rack::CommonCookies
11
+ run lambda {|env| [200, {'Set-Cookie' => env['HTTP_COOKIE']}, []] }
12
+ end
13
+ end
14
+
15
+ def request
16
+ Rack::MockRequest.new(@app)
17
+ end
18
+
19
+ def make_request(domain, cookies='key=value')
20
+ request.get '/', 'HTTP_COOKIE' => cookies, 'HTTP_HOST' => domain
21
+ end
22
+
23
+ specify 'should use .domain.com for cookies from domain.com' do
24
+ response = make_request 'domain.com'
25
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com'
26
+ end
27
+
28
+ specify 'should use .domain.com for cookies from www.domain.com' do
29
+ response = make_request 'www.domain.com'
30
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com'
31
+ end
32
+
33
+ specify 'should use .domain.com for cookies from subdomain.domain.com' do
34
+ response = make_request 'subdomain.domain.com'
35
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com'
36
+ end
37
+
38
+ specify 'should use .domain.com for cookies from 0.subdomain1.subdomain2.domain.com' do
39
+ response = make_request '0.subdomain1.subdomain2.domain.com'
40
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com'
41
+ end
42
+
43
+ specify 'should use .domain.local for cookies from domain.local' do
44
+ response = make_request '0.subdomain1.subdomain2.domain.com'
45
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com'
46
+ end
47
+
48
+ specify 'should use .domain.local for cookies from subdomain.domain.local' do
49
+ response = make_request 'subdomain.domain.local'
50
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.local'
51
+ end
52
+
53
+ specify 'should use .domain.com.ua for cookies from domain.com.ua' do
54
+ response = make_request 'domain.com.ua'
55
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com.ua'
56
+ end
57
+
58
+ specify 'should use .domain.com.ua for cookies from subdomain.domain.com.ua' do
59
+ response = make_request 'subdomain.domain.com.ua'
60
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.com.ua'
61
+ end
62
+
63
+ specify 'should use .domain.co.uk for cookies from domain.co.uk' do
64
+ response = make_request 'domain.co.uk'
65
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.co.uk'
66
+ end
67
+
68
+ specify 'should use .domain.co.uk for cookies from subdomain.domain.co.uk' do
69
+ response = make_request 'subdomain.domain.co.uk'
70
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.co.uk'
71
+ end
72
+
73
+ specify 'should use .domain.eu.com for cookies from domain.eu.com' do
74
+ response = make_request 'domain.eu.com'
75
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.eu.com'
76
+ end
77
+
78
+ specify 'should use .domain.eu.com for cookies from subdomain.domain.eu.com' do
79
+ response = make_request 'subdomain.domain.eu.com'
80
+ response.headers['Set-Cookie'].should == 'key=value; domain=.domain.eu.com'
81
+ end
82
+
83
+ specify 'should work with multiple cookies' do
84
+ response = make_request 'sub.domain.bz', "key=value\nkey1=value2"
85
+ response.headers['Set-Cookie'].should == "key=value; domain=.domain.bz\nkey1=value2; domain=.domain.bz"
86
+ end
87
+
88
+ specify 'should work with cookies which have explicit domain' do
89
+ response = make_request 'sub.domain.bz', "key=value; domain=domain.bz"
90
+ response.headers['Set-Cookie'].should == "key=value; domain=.domain.bz"
91
+ end
92
+
93
+ specify 'should not touch cookies if domain is localhost' do
94
+ response = make_request 'localhost'
95
+ response.headers['Set-Cookie'].should == "key=value"
96
+ end
97
+
98
+ specify 'should not touch cookies if domain is ip address' do
99
+ response = make_request '127.0.0.1'
100
+ response.headers['Set-Cookie'].should == "key=value"
101
+ end
102
+
103
+ specify 'should use .domain.com for cookies from subdomain.domain.com:3000' do
104
+ response = make_request 'subdomain.domain.com:3000'
105
+ response.headers['Set-Cookie'].should == "key=value; domain=.domain.com"
106
+ end
107
+ end
@@ -69,5 +69,13 @@ context "Rack::JSONP" do
69
69
  body = Rack::JSONP.new(app).call(request).last
70
70
  body.should.equal [test_body]
71
71
  end
72
+
73
+ specify "should not change anything if there is no Content-Type header" do
74
+ test_body = '<html><body>404 Not Found</body></html>'
75
+ app = lambda { |env| [404, {}, [test_body]] }
76
+ request = Rack::MockRequest.env_for("/", :params => "callback=foo", 'HTTP_ACCEPT' => 'application/json')
77
+ body = Rack::JSONP.new(app).call(request).last
78
+ body.should.equal [test_body]
79
+ end
72
80
 
73
81
  end
@@ -91,6 +91,80 @@ begin
91
91
  STDERR.puts 'WARN: Skipping SMTP tests (edit test/mail_settings.rb to enable)'
92
92
  end
93
93
 
94
+ context 'for tls enabled smtp' do
95
+ setup do
96
+ @smtp_settings.merge!(TEST_SMTP_TLS)
97
+ @mailer =
98
+ Rack::MailExceptions.new(@app) do |mail|
99
+ mail.to TEST_SMTP_TLS.values_at(:user_name, :domain).join('@')
100
+ mail.from 'bar@example.org'
101
+ mail.subject '[ERROR] %s'
102
+ mail.smtp @smtp_settings.merge( :enable_starttls_auto => true)
103
+ end
104
+ end
105
+
106
+ describe 'with :enable_starttls_auto set to :auto' do
107
+ specify 'sends mail' do
108
+ @mailer.smtp.merge(:enable_starttls_auto => :auto)
109
+ lambda { @mailer.call(@env) }.should.raise(TestError)
110
+ @env['mail.sent'].should.be true
111
+ end
112
+ end
113
+
114
+ describe 'with :enable_starttls_auto set to true' do
115
+ specify 'sends mail' do
116
+ @mailer.smtp.merge(:enable_starttls_auto => true)
117
+ lambda { @mailer.call(@env) }.should.raise(TestError)
118
+ @env['mail.sent'].should.be true
119
+ end
120
+ end
121
+ end if defined?(TEST_SMTP_TLS)
122
+
123
+ describe 'for tls enabled fake smtp' do
124
+ class FakeSMTP
125
+ def initialize(*args); @@_tls = nil; end
126
+ def start(*args); end
127
+ def enable_starttls_auto; @@_tls = :auto; end
128
+ def enable_starttls; @@_tls = true; end
129
+ def send_message(*args); end
130
+ def self.tls; @@_tls; end
131
+ end
132
+
133
+ setup do
134
+ Rack::MailExceptions.class_eval { def service; FakeSMTP; end}
135
+ @mailer =
136
+ Rack::MailExceptions.new(@app) do |mail|
137
+ mail.to 'foo@example.org'
138
+ mail.from 'bar@example.org'
139
+ mail.subject '[ERROR] %s'
140
+ mail.smtp @smtp_settings.merge( :server => 'server.com')
141
+ end
142
+ end
143
+
144
+ context 'with :enable_starttls_auto unset' do
145
+ specify 'sends mail' do
146
+ @mailer.smtp[:enable_starttls_auto] = nil
147
+ lambda { @mailer.call(@env) }.should.raise(TestError)
148
+ FakeSMTP.tls.should.be nil
149
+ end
150
+ end
151
+
152
+ context 'with :enable_starttls_auto set to true' do
153
+ specify 'sends mail' do
154
+ @mailer.smtp[:enable_starttls_auto] = true
155
+ lambda { @mailer.call(@env) }.should.raise(TestError)
156
+ FakeSMTP.tls.should == true
157
+ end
158
+ end
159
+
160
+ context 'with :enable_starttls_auto set to :auto' do
161
+ specify 'sends mail' do
162
+ @mailer.smtp[:enable_starttls_auto] = :auto
163
+ lambda { @mailer.call(@env) }.should.raise(TestError)
164
+ FakeSMTP.tls.should == :auto
165
+ end
166
+ end
167
+ end
94
168
  end
95
169
  rescue LoadError => boom
96
170
  STDERR.puts "WARN: Skipping Rack::MailExceptions tests (tmail not installed)"
@@ -0,0 +1,44 @@
1
+ require 'test/spec'
2
+
3
+ require 'rack'
4
+ require 'rack/contrib/try_static'
5
+ require 'rack/mock'
6
+
7
+ def request(options = {})
8
+ options.merge!({
9
+ :urls => %w[/],
10
+ :root => ::File.expand_path(::File.dirname(__FILE__)),
11
+ })
12
+
13
+ @request =
14
+ Rack::MockRequest.new(
15
+ Rack::TryStatic.new(
16
+ lambda {[200, {}, ["Hello World"]]},
17
+ options))
18
+ end
19
+
20
+ describe "Rack::TryStatic" do
21
+ context 'when file cannot be found' do
22
+ it 'should call call app' do
23
+ res = request(:try => ['html']).get('/documents')
24
+ res.should.be.ok
25
+ res.body.should == "Hello World"
26
+ end
27
+ end
28
+
29
+ context 'when file can be found' do
30
+ it 'should serve first found' do
31
+ res = request(:try => ['.html', '/index.html', '/index.htm']).get('/documents')
32
+ res.should.be.ok
33
+ res.body.strip.should == "index.html"
34
+ end
35
+ end
36
+
37
+ context 'when path_info maps directly to file' do
38
+ it 'should serve existing' do
39
+ res = request(:try => ['/index.html']).get('/documents/existing.html')
40
+ res.should.be.ok
41
+ res.body.strip.should == "existing.html"
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-contrib
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 19
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
- - 0
8
8
  - 1
9
- version: 1.0.1
9
+ - 0
10
+ version: 1.1.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - rack-devel
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-06-09 00:00:00 -07:00
18
+ date: 2010-10-19 00:00:00 -07:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: rack
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 57
27
30
  segments:
28
31
  - 0
29
32
  - 9
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: test-spec
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 59
41
46
  segments:
42
47
  - 0
43
48
  - 9
@@ -49,9 +54,11 @@ dependencies:
49
54
  name: tmail
50
55
  prerelease: false
51
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
61
+ hash: 11
55
62
  segments:
56
63
  - 1
57
64
  - 2
@@ -62,9 +69,11 @@ dependencies:
62
69
  name: json
63
70
  prerelease: false
64
71
  requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
65
73
  requirements:
66
74
  - - ">="
67
75
  - !ruby/object:Gem::Version
76
+ hash: 13
68
77
  segments:
69
78
  - 1
70
79
  - 1
@@ -91,6 +100,7 @@ files:
91
100
  - lib/rack/contrib/backstage.rb
92
101
  - lib/rack/contrib/bounce_favicon.rb
93
102
  - lib/rack/contrib/callbacks.rb
103
+ - lib/rack/contrib/common_cookies.rb
94
104
  - lib/rack/contrib/config.rb
95
105
  - lib/rack/contrib/cookies.rb
96
106
  - lib/rack/contrib/csshttprequest.rb
@@ -118,15 +128,20 @@ files:
118
128
  - lib/rack/contrib/simple_endpoint.rb
119
129
  - lib/rack/contrib/static_cache.rb
120
130
  - lib/rack/contrib/time_zone.rb
131
+ - lib/rack/contrib/try_static.rb
121
132
  - rack-contrib.gemspec
122
133
  - test/404.html
123
134
  - test/Maintenance.html
135
+ - test/documents/existing.html
136
+ - test/documents/index.htm
137
+ - test/documents/index.html
124
138
  - test/documents/test
125
139
  - test/mail_settings.rb
126
140
  - test/spec_rack_accept_format.rb
127
141
  - test/spec_rack_access.rb
128
142
  - test/spec_rack_backstage.rb
129
143
  - test/spec_rack_callbacks.rb
144
+ - test/spec_rack_common_cookies.rb
130
145
  - test/spec_rack_config.rb
131
146
  - test/spec_rack_contrib.rb
132
147
  - test/spec_rack_cookies.rb
@@ -151,6 +166,7 @@ files:
151
166
  - test/spec_rack_sendfile.rb
152
167
  - test/spec_rack_simple_endpoint.rb
153
168
  - test/spec_rack_static_cache.rb
169
+ - test/spec_rack_try_static.rb
154
170
  - test/statics/test
155
171
  has_rdoc: true
156
172
  homepage: http://github.com/rack/rack-contrib/
@@ -167,23 +183,27 @@ rdoc_options:
167
183
  require_paths:
168
184
  - lib
169
185
  required_ruby_version: !ruby/object:Gem::Requirement
186
+ none: false
170
187
  requirements:
171
188
  - - ">="
172
189
  - !ruby/object:Gem::Version
190
+ hash: 3
173
191
  segments:
174
192
  - 0
175
193
  version: "0"
176
194
  required_rubygems_version: !ruby/object:Gem::Requirement
195
+ none: false
177
196
  requirements:
178
197
  - - ">="
179
198
  - !ruby/object:Gem::Version
199
+ hash: 3
180
200
  segments:
181
201
  - 0
182
202
  version: "0"
183
203
  requirements: []
184
204
 
185
205
  rubyforge_project:
186
- rubygems_version: 1.3.6
206
+ rubygems_version: 1.3.7
187
207
  signing_key:
188
208
  specification_version: 2
189
209
  summary: Contributed Rack Middleware and Utilities
@@ -192,6 +212,7 @@ test_files:
192
212
  - test/spec_rack_access.rb
193
213
  - test/spec_rack_backstage.rb
194
214
  - test/spec_rack_callbacks.rb
215
+ - test/spec_rack_common_cookies.rb
195
216
  - test/spec_rack_config.rb
196
217
  - test/spec_rack_contrib.rb
197
218
  - test/spec_rack_cookies.rb
@@ -216,3 +237,4 @@ test_files:
216
237
  - test/spec_rack_sendfile.rb
217
238
  - test/spec_rack_simple_endpoint.rb
218
239
  - test/spec_rack_static_cache.rb
240
+ - test/spec_rack_try_static.rb