rack 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- data/{README → README.rdoc} +17 -0
- data/Rakefile +2 -2
- data/contrib/rack_logo.svg +1 -1
- data/lib/rack.rb +1 -0
- data/lib/rack/auth/digest/md5.rb +1 -1
- data/lib/rack/auth/digest/request.rb +7 -6
- data/lib/rack/backports/uri/common.rb +19 -13
- data/lib/rack/body_proxy.rb +29 -0
- data/lib/rack/builder.rb +1 -1
- data/lib/rack/commonlogger.rb +3 -1
- data/lib/rack/etag.rb +3 -2
- data/lib/rack/handler/fastcgi.rb +1 -1
- data/lib/rack/handler/scgi.rb +1 -1
- data/lib/rack/handler/webrick.rb +1 -1
- data/lib/rack/lock.rb +2 -21
- data/lib/rack/mock.rb +4 -1
- data/lib/rack/multipart/generator.rb +1 -1
- data/lib/rack/multipart/parser.rb +1 -1
- data/lib/rack/multipart/uploaded_file.rb +4 -0
- data/lib/rack/sendfile.rb +3 -4
- data/lib/rack/server.rb +5 -5
- data/lib/rack/session/abstract/id.rb +4 -2
- data/lib/rack/utils.rb +6 -6
- data/rack.gemspec +3 -3
- data/test/spec_body_proxy.rb +43 -0
- data/test/spec_mock.rb +18 -0
- data/test/spec_response.rb +7 -0
- data/test/spec_session_cookie.rb +6 -0
- data/test/spec_utils.rb +23 -2
- metadata +10 -9
data/{README → README.rdoc}
RENAMED
@@ -337,6 +337,21 @@ run on port 11211) and memcache-client installed.
|
|
337
337
|
* Cookies respect renew
|
338
338
|
* Session middleware uses SecureRandom.hex
|
339
339
|
|
340
|
+
* May 22nd, 2011: Fourteenth public release 1.2.3
|
341
|
+
* Pulled in relevant bug fixes from 1.3
|
342
|
+
* Fixed 1.8.6 support
|
343
|
+
|
344
|
+
* July 13, 2011: Fifteenth public release 1.3.1
|
345
|
+
* Fix 1.9.1 support
|
346
|
+
* Fix JRuby support
|
347
|
+
* Properly handle $KCODE in Rack::Utils.escape
|
348
|
+
* Make method_missing/respond_to behavior consistent for Rack::Lock,
|
349
|
+
Rack::Auth::Digest::Request and Rack::Multipart::UploadedFile
|
350
|
+
* Reenable passing rack.session to session middleware
|
351
|
+
* Rack::CommonLogger handles streaming responses correctly
|
352
|
+
* Rack::MockResponse calls close on the body object
|
353
|
+
* Fix a DOS vector from MRI stdlib backport
|
354
|
+
|
340
355
|
== Contact
|
341
356
|
|
342
357
|
Please post bugs, suggestions and patches to
|
@@ -361,6 +376,8 @@ The Rack Core Team, consisting of
|
|
361
376
|
* Michael Fellinger (manveru)
|
362
377
|
* Ryan Tomayko (rtomayko)
|
363
378
|
* Scytrin dai Kinthra (scytrin)
|
379
|
+
* Aaron Patterson (tenderlove)
|
380
|
+
* Konstantin Haase (rkh)
|
364
381
|
|
365
382
|
would like to thank:
|
366
383
|
|
data/Rakefile
CHANGED
@@ -86,9 +86,9 @@ end
|
|
86
86
|
|
87
87
|
desc "Generate RDoc documentation"
|
88
88
|
task :rdoc => ["SPEC"] do
|
89
|
-
sh(*%w{rdoc --line-numbers --main README
|
89
|
+
sh(*%w{rdoc --line-numbers --main README.rdoc
|
90
90
|
--title 'Rack\ Documentation' --charset utf-8 -U -o doc} +
|
91
|
-
%w{README KNOWN-ISSUES SPEC} +
|
91
|
+
%w{README.rdoc KNOWN-ISSUES SPEC} +
|
92
92
|
Dir["lib/**/*.rb"])
|
93
93
|
end
|
94
94
|
|
data/contrib/rack_logo.svg
CHANGED
data/lib/rack.rb
CHANGED
data/lib/rack/auth/digest/md5.rb
CHANGED
@@ -24,7 +24,7 @@ module Rack
|
|
24
24
|
def initialize(app, realm=nil, opaque=nil, &authenticator)
|
25
25
|
@passwords_hashed = nil
|
26
26
|
if opaque.nil? and realm.respond_to? :values_at
|
27
|
-
realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed
|
27
|
+
realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed
|
28
28
|
end
|
29
29
|
super(app, realm, &authenticator)
|
30
30
|
@opaque = opaque
|
@@ -6,7 +6,6 @@ module Rack
|
|
6
6
|
module Auth
|
7
7
|
module Digest
|
8
8
|
class Request < Auth::AbstractRequest
|
9
|
-
|
10
9
|
def method
|
11
10
|
@env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD']
|
12
11
|
end
|
@@ -27,13 +26,15 @@ module Rack
|
|
27
26
|
@params ||= Params.parse(parts.last)
|
28
27
|
end
|
29
28
|
|
30
|
-
def
|
31
|
-
|
32
|
-
return params[key]
|
33
|
-
end
|
34
|
-
super
|
29
|
+
def respond_to?(sym, *)
|
30
|
+
super or params.has_key? sym.to_s
|
35
31
|
end
|
36
32
|
|
33
|
+
def method_missing(sym, *args)
|
34
|
+
return super unless params.has_key?(key = sym.to_s)
|
35
|
+
return params[key] if args.size == 0
|
36
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
|
37
|
+
end
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
@@ -20,20 +20,26 @@ module URI
|
|
20
20
|
#
|
21
21
|
# See URI.decode_www_form_component, URI.encode_www_form
|
22
22
|
def self.encode_www_form_component(str)
|
23
|
-
if
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
if RUBY_VERSION < "1.9" && $KCODE =~ /u/i
|
24
|
+
str.gsub(/([^ a-zA-Z0-9_.-]+)/) do
|
25
|
+
'%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase
|
26
|
+
end.tr(' ', '+')
|
27
|
+
else
|
28
|
+
if TBLENCWWWCOMP_.empty?
|
29
|
+
tbl = {}
|
30
|
+
256.times do |i|
|
31
|
+
tbl[i.chr] = '%%%02X' % i
|
32
|
+
end
|
33
|
+
tbl[' '] = '+'
|
34
|
+
begin
|
35
|
+
TBLENCWWWCOMP_.replace(tbl)
|
36
|
+
TBLENCWWWCOMP_.freeze
|
37
|
+
rescue
|
38
|
+
end
|
33
39
|
end
|
40
|
+
str = str.to_s
|
41
|
+
str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
|
34
42
|
end
|
35
|
-
str = str.to_s
|
36
|
-
str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
|
37
43
|
end
|
38
44
|
|
39
45
|
# Decode given +str+ of URL-encoded form data.
|
@@ -58,7 +64,7 @@ module URI
|
|
58
64
|
rescue
|
59
65
|
end
|
60
66
|
end
|
61
|
-
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%]
|
67
|
+
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str
|
62
68
|
str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
|
63
69
|
end
|
64
70
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rack
|
2
|
+
class BodyProxy
|
3
|
+
def initialize(body, &block)
|
4
|
+
@body, @block, @closed = body, block, false
|
5
|
+
end
|
6
|
+
|
7
|
+
def respond_to?(*args)
|
8
|
+
super or @body.respond_to?(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def close
|
12
|
+
raise IOError, "closed stream" if @closed
|
13
|
+
begin
|
14
|
+
@body.close if @body.respond_to? :close
|
15
|
+
ensure
|
16
|
+
@block.call
|
17
|
+
@closed = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def closed?
|
22
|
+
@closed
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(*args, &block)
|
26
|
+
@body.__send__(*args, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rack/builder.rb
CHANGED
@@ -113,7 +113,7 @@ module Rack
|
|
113
113
|
# end
|
114
114
|
# end
|
115
115
|
#
|
116
|
-
# This example includes a piece of middleware which will run before requests hit +Heartbeat+.
|
116
|
+
# This example includes a piece of middleware which will run before requests hit +Heartbeat+.
|
117
117
|
#
|
118
118
|
def map(path, &block)
|
119
119
|
if @ins.last.kind_of? Hash
|
data/lib/rack/commonlogger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rack/body_proxy'
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
# Rack::CommonLogger forwards every request to an +app+ given, and
|
3
5
|
# logs a line in the Apache common log format to the +logger+, or
|
@@ -17,7 +19,7 @@ module Rack
|
|
17
19
|
began_at = Time.now
|
18
20
|
status, header, body = @app.call(env)
|
19
21
|
header = Utils::HeaderHash.new(header)
|
20
|
-
log(env, status, header, began_at)
|
22
|
+
body = BodyProxy.new(body) { log(env, status, header, began_at) }
|
21
23
|
[status, header, body]
|
22
24
|
end
|
23
25
|
|
data/lib/rack/etag.rb
CHANGED
@@ -9,7 +9,7 @@ module Rack
|
|
9
9
|
#
|
10
10
|
# On initialization, you can pass two parameters: a Cache-Control directive
|
11
11
|
# used when Etag is absent and a directive when it is present. The first
|
12
|
-
# defaults to nil, while the second defaults to "max-age=0,
|
12
|
+
# defaults to nil, while the second defaults to "max-age=0, private, must-revalidate"
|
13
13
|
class ETag
|
14
14
|
DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze
|
15
15
|
|
@@ -28,7 +28,8 @@ module Rack
|
|
28
28
|
end
|
29
29
|
|
30
30
|
unless headers['Cache-Control']
|
31
|
-
headers['Cache-Control'] =
|
31
|
+
headers['Cache-Control'] =
|
32
|
+
(digest ? @cache_control : @no_cache_control) || []
|
32
33
|
end
|
33
34
|
|
34
35
|
[status, headers, body]
|
data/lib/rack/handler/fastcgi.rb
CHANGED
data/lib/rack/handler/scgi.rb
CHANGED
data/lib/rack/handler/webrick.rb
CHANGED
data/lib/rack/lock.rb
CHANGED
@@ -1,27 +1,8 @@
|
|
1
1
|
require 'thread'
|
2
|
+
require 'rack/body_proxy'
|
2
3
|
|
3
4
|
module Rack
|
4
5
|
class Lock
|
5
|
-
class Proxy < Struct.new(:target, :mutex) # :nodoc:
|
6
|
-
def each
|
7
|
-
target.each { |x| yield x }
|
8
|
-
end
|
9
|
-
|
10
|
-
def close
|
11
|
-
target.close if target.respond_to?(:close)
|
12
|
-
ensure
|
13
|
-
mutex.unlock
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_path
|
17
|
-
target.to_path
|
18
|
-
end
|
19
|
-
|
20
|
-
def respond_to?(sym)
|
21
|
-
sym.to_sym == :close || target.respond_to?(sym)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
6
|
FLAG = 'rack.multithread'.freeze
|
26
7
|
|
27
8
|
def initialize(app, mutex = Mutex.new)
|
@@ -32,7 +13,7 @@ module Rack
|
|
32
13
|
old, env[FLAG] = env[FLAG], false
|
33
14
|
@mutex.lock
|
34
15
|
response = @app.call(env)
|
35
|
-
response[2] =
|
16
|
+
response[2] = BodyProxy.new(response[2]) { @mutex.unlock }
|
36
17
|
response
|
37
18
|
rescue Exception
|
38
19
|
@mutex.unlock
|
data/lib/rack/mock.rb
CHANGED
@@ -68,7 +68,10 @@ module Rack
|
|
68
68
|
end
|
69
69
|
|
70
70
|
errors = env["rack.errors"]
|
71
|
-
|
71
|
+
status, headers, body = app.call(env)
|
72
|
+
MockResponse.new(status, headers, body, errors)
|
73
|
+
ensure
|
74
|
+
body.close if body.respond_to?(:close)
|
72
75
|
end
|
73
76
|
|
74
77
|
# Return the Rack environment used for a request to +uri+.
|
data/lib/rack/sendfile.rb
CHANGED
@@ -47,10 +47,9 @@ module Rack
|
|
47
47
|
# }
|
48
48
|
#
|
49
49
|
# Note that the X-Sendfile-Type header must be set exactly as shown above. The
|
50
|
-
# X-Accel-Mapping header should specify the
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# resulting path.
|
50
|
+
# X-Accel-Mapping header should specify the internal URI path, followed by an
|
51
|
+
# equals sign (=), followed name of the location in the file system that it maps
|
52
|
+
# to. The middleware performs a simple substitution on the resulting path.
|
54
53
|
#
|
55
54
|
# See Also: http://wiki.codemongers.com/NginxXSendfile
|
56
55
|
#
|
data/lib/rack/server.rb
CHANGED
@@ -47,11 +47,11 @@ module Rack
|
|
47
47
|
opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
|
48
48
|
options[:Port] = port
|
49
49
|
}
|
50
|
-
|
50
|
+
|
51
51
|
opts.on("-O", "--option NAME[=VALUE]", "pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} -s SERVER -h' to get a list of options for SERVER") { |name|
|
52
52
|
name, value = name.split('=', 2)
|
53
53
|
value = true if value.nil?
|
54
|
-
options[name.to_sym] = value
|
54
|
+
options[name.to_sym] = value
|
55
55
|
}
|
56
56
|
|
57
57
|
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
@@ -72,7 +72,7 @@ module Rack
|
|
72
72
|
opts.on_tail("-h", "-?", "--help", "Show this message") do
|
73
73
|
puts opts
|
74
74
|
puts handler_opts(options)
|
75
|
-
|
75
|
+
|
76
76
|
exit
|
77
77
|
end
|
78
78
|
|
@@ -92,7 +92,7 @@ module Rack
|
|
92
92
|
options[:config] = args.last if args.last
|
93
93
|
options
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
def handler_opts(options)
|
97
97
|
begin
|
98
98
|
info = []
|
@@ -100,7 +100,7 @@ module Rack
|
|
100
100
|
if server && server.respond_to?(:valid_options)
|
101
101
|
info << ""
|
102
102
|
info << "Server-specific options for #{server.name}:"
|
103
|
-
|
103
|
+
|
104
104
|
has_options = false
|
105
105
|
server.valid_options.each do |name, description|
|
106
106
|
next if name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # ignore handler's host and port options, we do our own.
|
@@ -214,7 +214,7 @@ module Rack
|
|
214
214
|
else
|
215
215
|
"%0#{@sid_length}x" % Kernel.rand(2**@sidbits - 1)
|
216
216
|
end
|
217
|
-
rescue
|
217
|
+
rescue NotImplementedError
|
218
218
|
generate_sid(false)
|
219
219
|
end
|
220
220
|
|
@@ -222,8 +222,10 @@ module Rack
|
|
222
222
|
# metadata into 'rack.session.options'.
|
223
223
|
|
224
224
|
def prepare_session(env)
|
225
|
-
env[ENV_SESSION_KEY]
|
225
|
+
session_was = env[ENV_SESSION_KEY]
|
226
|
+
env[ENV_SESSION_KEY] = SessionHash.new(self, env)
|
226
227
|
env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options)
|
228
|
+
env[ENV_SESSION_KEY].merge! session_was if session_was
|
227
229
|
end
|
228
230
|
|
229
231
|
# Extracts the session id from provided cookies and passes it and the
|
data/lib/rack/utils.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
-
|
3
2
|
require 'fileutils'
|
4
3
|
require 'set'
|
5
4
|
require 'tempfile'
|
6
|
-
|
7
5
|
require 'rack/multipart'
|
8
6
|
|
9
|
-
|
7
|
+
major, minor, patch = RUBY_VERSION.split('.').map { |v| v.to_i }
|
8
|
+
|
9
|
+
if (major == 1 && minor < 9) || (major == 1 && minor == 9 && patch < 2)
|
10
10
|
# pull in backports
|
11
11
|
require 'rack/backports/uri/common'
|
12
12
|
else
|
@@ -351,9 +351,9 @@ module Rack
|
|
351
351
|
end
|
352
352
|
|
353
353
|
def to_hash
|
354
|
-
|
355
|
-
|
356
|
-
|
354
|
+
hash = {}
|
355
|
+
each { |k,v| hash[k] = v }
|
356
|
+
hash
|
357
357
|
end
|
358
358
|
|
359
359
|
def [](k)
|
data/rack.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rack"
|
3
|
-
s.version = "1.3.
|
3
|
+
s.version = "1.3.1"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.summary = "a modular Ruby webserver interface"
|
6
6
|
|
@@ -15,11 +15,11 @@ Also see http://rack.rubyforge.org.
|
|
15
15
|
EOF
|
16
16
|
|
17
17
|
s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*,test/**/*}'] +
|
18
|
-
%w(COPYING KNOWN-ISSUES rack.gemspec Rakefile README SPEC)
|
18
|
+
%w(COPYING KNOWN-ISSUES rack.gemspec Rakefile README.rdoc SPEC)
|
19
19
|
s.bindir = 'bin'
|
20
20
|
s.executables << 'rackup'
|
21
21
|
s.require_path = 'lib'
|
22
|
-
s.extra_rdoc_files = ['README', 'KNOWN-ISSUES']
|
22
|
+
s.extra_rdoc_files = ['README.rdoc', 'KNOWN-ISSUES']
|
23
23
|
s.test_files = Dir['test/spec_*.rb']
|
24
24
|
|
25
25
|
s.author = 'Christian Neukirchen'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rack/body_proxy'
|
2
|
+
|
3
|
+
describe Rack::BodyProxy do
|
4
|
+
should 'call each on the wrapped body' do
|
5
|
+
called = false
|
6
|
+
proxy = Rack::BodyProxy.new(['foo']) { }
|
7
|
+
proxy.each do |str|
|
8
|
+
called = true
|
9
|
+
str.should.equal 'foo'
|
10
|
+
end
|
11
|
+
called.should.equal true
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'call close on the wrapped body' do
|
15
|
+
body = StringIO.new
|
16
|
+
proxy = Rack::BodyProxy.new(body) { }
|
17
|
+
proxy.close
|
18
|
+
body.should.be.closed
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'only call close on the wrapped body if it responds to close' do
|
22
|
+
body = []
|
23
|
+
proxy = Rack::BodyProxy.new(body) { }
|
24
|
+
proc { proxy.close }.should.not.raise
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'call the passed block on close' do
|
28
|
+
called = false
|
29
|
+
proxy = Rack::BodyProxy.new([]) { called = true }
|
30
|
+
called.should.equal false
|
31
|
+
proxy.close
|
32
|
+
called.should.equal true
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'not close more than one time' do
|
36
|
+
count = 0
|
37
|
+
proxy = Rack::BodyProxy.new([]) { count += 1; raise "Block invoked more than 1 time!" if count > 1 }
|
38
|
+
proxy.close
|
39
|
+
lambda {
|
40
|
+
proxy.close
|
41
|
+
}.should.raise(IOError)
|
42
|
+
end
|
43
|
+
end
|
data/test/spec_mock.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'rack/mock'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
5
|
app = lambda { |env|
|
5
6
|
req = Rack::Request.new(env)
|
@@ -183,6 +184,15 @@ describe Rack::MockRequest do
|
|
183
184
|
get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
|
184
185
|
}.should.not.raise(Rack::Lint::LintError)
|
185
186
|
end
|
187
|
+
|
188
|
+
should "call close on the original body object" do
|
189
|
+
called = false
|
190
|
+
body = Rack::BodyProxy.new(['hi']) { called = true }
|
191
|
+
capp = proc { |e| [200, {'Content-Type' => 'text/plain '}, body] }
|
192
|
+
called.should.equal false
|
193
|
+
Rack::MockRequest.new(capp).get('/', :lint => true)
|
194
|
+
called.should.equal true
|
195
|
+
end
|
186
196
|
end
|
187
197
|
|
188
198
|
describe Rack::MockResponse do
|
@@ -233,6 +243,14 @@ describe Rack::MockResponse do
|
|
233
243
|
res.errors.should.include "foo"
|
234
244
|
end
|
235
245
|
|
246
|
+
should "allow calling body.close afterwards" do
|
247
|
+
# this is exactly what rack-test does
|
248
|
+
body = StringIO.new("hi")
|
249
|
+
res = Rack::MockResponse.new(200, {}, body)
|
250
|
+
body.close if body.respond_to?(:close)
|
251
|
+
res.body.should == 'hi'
|
252
|
+
end
|
253
|
+
|
236
254
|
should "optionally make Rack errors fatal" do
|
237
255
|
lambda {
|
238
256
|
Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
|
data/test/spec_response.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'set'
|
2
2
|
require 'rack/response'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
5
|
describe Rack::Response do
|
5
6
|
should "have sensible default values" do
|
@@ -243,4 +244,10 @@ describe Rack::Response do
|
|
243
244
|
res.headers["Content-Length"].should.equal "8"
|
244
245
|
end
|
245
246
|
|
247
|
+
it "calls close on #body" do
|
248
|
+
res = Rack::Response.new
|
249
|
+
res.body = StringIO.new
|
250
|
+
res.close
|
251
|
+
res.body.should.be.closed
|
252
|
+
end
|
246
253
|
end
|
data/test/spec_session_cookie.rb
CHANGED
@@ -207,4 +207,10 @@ describe Rack::Session::Cookie do
|
|
207
207
|
res = Rack::MockRequest.new(app).get("/")
|
208
208
|
res.body.should.match(/Base64::Marshal/)
|
209
209
|
end
|
210
|
+
|
211
|
+
it "allows passing in a hash with session data from middleware in front" do
|
212
|
+
app = Rack::Session::Cookie.new(session_id)
|
213
|
+
res = Rack::MockRequest.new(app).get("/", 'rack.session' => {:foo => 'bar'})
|
214
|
+
res.body.should.match(/foo/)
|
215
|
+
end
|
210
216
|
end
|
data/test/spec_utils.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
2
|
require 'rack/utils'
|
4
3
|
require 'rack/mock'
|
5
4
|
|
@@ -20,6 +19,28 @@ describe Rack::Utils do
|
|
20
19
|
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
21
20
|
end
|
22
21
|
|
22
|
+
if RUBY_VERSION[/^\d+\.\d+/] == '1.8'
|
23
|
+
should "escape correctly for multibyte characters if $KCODE is set to 'U'" do
|
24
|
+
default_kcode, $KCODE = $KCODE, 'U'
|
25
|
+
|
26
|
+
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
27
|
+
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
28
|
+
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
29
|
+
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
30
|
+
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
31
|
+
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
32
|
+
|
33
|
+
$KCODE = default_kcode
|
34
|
+
end
|
35
|
+
|
36
|
+
should "unescape multibyte characters correctly if $KCODE is set to 'U'" do
|
37
|
+
default_kcode, $KCODE = $KCODE, 'U'
|
38
|
+
Rack::Utils.unescape('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8').should.equal(
|
39
|
+
"\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0])
|
40
|
+
$KCODE = default_kcode
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
23
44
|
if "".respond_to?(:encode)
|
24
45
|
should "escape non-UTF8 strings" do
|
25
46
|
Rack::Utils.escape("ø".encode("ISO-8859-1")).should.equal "%F8"
|
@@ -76,7 +97,7 @@ describe Rack::Utils do
|
|
76
97
|
should.equal "foo" => "bar", "baz" => ""
|
77
98
|
Rack::Utils.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
78
99
|
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
79
|
-
|
100
|
+
|
80
101
|
Rack::Utils.parse_nested_query("a=b&pid%3D1234=1023").
|
81
102
|
should.equal "pid=1234" => "1023", "a" => "b"
|
82
103
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 1
|
10
|
+
version: 1.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian Neukirchen
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-07-13 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: bacon
|
@@ -117,7 +116,7 @@ executables:
|
|
117
116
|
extensions: []
|
118
117
|
|
119
118
|
extra_rdoc_files:
|
120
|
-
- README
|
119
|
+
- README.rdoc
|
121
120
|
- KNOWN-ISSUES
|
122
121
|
files:
|
123
122
|
- bin/rackup
|
@@ -133,6 +132,7 @@ files:
|
|
133
132
|
- lib/rack/auth/digest/params.rb
|
134
133
|
- lib/rack/auth/digest/request.rb
|
135
134
|
- lib/rack/backports/uri/common.rb
|
135
|
+
- lib/rack/body_proxy.rb
|
136
136
|
- lib/rack/builder.rb
|
137
137
|
- lib/rack/cascade.rb
|
138
138
|
- lib/rack/chunked.rb
|
@@ -219,6 +219,7 @@ files:
|
|
219
219
|
- test/registering_handler/rack/handler/registering_myself.rb
|
220
220
|
- test/spec_auth_basic.rb
|
221
221
|
- test/spec_auth_digest.rb
|
222
|
+
- test/spec_body_proxy.rb
|
222
223
|
- test/spec_builder.rb
|
223
224
|
- test/spec_cascade.rb
|
224
225
|
- test/spec_cgi.rb
|
@@ -269,9 +270,8 @@ files:
|
|
269
270
|
- KNOWN-ISSUES
|
270
271
|
- rack.gemspec
|
271
272
|
- Rakefile
|
272
|
-
- README
|
273
|
+
- README.rdoc
|
273
274
|
- SPEC
|
274
|
-
has_rdoc: true
|
275
275
|
homepage: http://rack.rubyforge.org
|
276
276
|
licenses: []
|
277
277
|
|
@@ -301,13 +301,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
301
|
requirements: []
|
302
302
|
|
303
303
|
rubyforge_project: rack
|
304
|
-
rubygems_version: 1.5
|
304
|
+
rubygems_version: 1.8.5
|
305
305
|
signing_key:
|
306
306
|
specification_version: 3
|
307
307
|
summary: a modular Ruby webserver interface
|
308
308
|
test_files:
|
309
309
|
- test/spec_auth_basic.rb
|
310
310
|
- test/spec_auth_digest.rb
|
311
|
+
- test/spec_body_proxy.rb
|
311
312
|
- test/spec_builder.rb
|
312
313
|
- test/spec_cascade.rb
|
313
314
|
- test/spec_cgi.rb
|