rack 1.0.0 → 1.0.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/RDOX +7 -2
- data/README +11 -0
- data/SPEC +3 -1
- data/lib/rack/deflater.rb +1 -1
- data/lib/rack/handler/cgi.rb +1 -1
- data/lib/rack/handler/fastcgi.rb +9 -7
- data/lib/rack/handler/lsws.rb +13 -8
- data/lib/rack/handler/mongrel.rb +5 -2
- data/lib/rack/handler/scgi.rb +6 -3
- data/lib/rack/handler/webrick.rb +6 -2
- data/lib/rack/lint.rb +10 -1
- data/lib/rack/mock.rb +6 -3
- data/lib/rack/reloader.rb +2 -2
- data/lib/rack/request.rb +1 -9
- data/lib/rack/rewindable_input.rb +2 -0
- data/lib/rack/utils.rb +14 -10
- data/rack.gemspec +3 -3
- data/test/multipart/semicolon +6 -0
- data/test/spec_rack_cgi.rb +1 -1
- data/test/spec_rack_fastcgi.rb +1 -1
- data/test/spec_rack_lint.rb +22 -0
- data/test/spec_rack_mock.rb +1 -1
- data/test/spec_rack_mongrel.rb +1 -1
- data/test/spec_rack_request.rb +5 -16
- data/test/spec_rack_utils.rb +46 -0
- data/test/spec_rack_webrick.rb +1 -1
- metadata +3 -2
data/RDOX
CHANGED
@@ -250,7 +250,6 @@
|
|
250
250
|
* does conform to the Rack spec
|
251
251
|
* should parse Accept-Encoding correctly
|
252
252
|
* should provide ip information
|
253
|
-
* memoizes itself to reduce the cost of repetitive initialization
|
254
253
|
* should allow subclass request to be instantiated after parent request
|
255
254
|
* should allow parent request to be instantiated after subclass request
|
256
255
|
|
@@ -379,6 +378,7 @@
|
|
379
378
|
|
380
379
|
== Rack::Utils
|
381
380
|
* should escape correctly
|
381
|
+
* should escape correctly for multibyte characters
|
382
382
|
* should unescape correctly
|
383
383
|
* should parse query strings correctly
|
384
384
|
* should parse nested query strings correctly
|
@@ -393,6 +393,10 @@
|
|
393
393
|
* should overwrite case insensitively and assume the new key's case
|
394
394
|
* should be converted to real Hash
|
395
395
|
* should convert Array values to Strings when converting to Hash
|
396
|
+
* should be able to delete the given key case-sensitively
|
397
|
+
* should be able to delete the given key case-insensitively
|
398
|
+
* should return the deleted value when #delete is called on an existing key
|
399
|
+
* should return nil when #delete is called on a non-existant key
|
396
400
|
|
397
401
|
== Rack::Utils::Context
|
398
402
|
* should set context correctly
|
@@ -405,6 +409,7 @@
|
|
405
409
|
* should parse multipart upload with nested parameters
|
406
410
|
* should parse multipart upload with binary file
|
407
411
|
* should parse multipart upload with empty file
|
412
|
+
* should parse multipart upload with filename with semicolons
|
408
413
|
* should not include file params if no file was selected
|
409
414
|
* should parse IE multipart upload and clean up filename
|
410
415
|
* rewinds input after parsing upload
|
@@ -420,4 +425,4 @@
|
|
420
425
|
* should correctly set cookies
|
421
426
|
* should provide a .run
|
422
427
|
|
423
|
-
|
428
|
+
335 specifications, 13 empty (1196 requirements), 0 failures
|
data/README
CHANGED
@@ -272,6 +272,17 @@ run on port 11211) and memcache-client installed.
|
|
272
272
|
* The Rakefile has been rewritten.
|
273
273
|
* Many bugfixes and small improvements.
|
274
274
|
|
275
|
+
* October 18th, 2009: Eighth public release 1.0.1.
|
276
|
+
* Bump remainder of rack.versions.
|
277
|
+
* Support the pure Ruby FCGI implementation.
|
278
|
+
* Fix for form names containing "=": split first then unescape components
|
279
|
+
* Fixes the handling of the filename parameter with semicolons in names.
|
280
|
+
* Add anchor to nested params parsing regexp to prevent stack overflows
|
281
|
+
* Use more compatible gzip write api instead of "<<".
|
282
|
+
* Make sure that Reloader doesn't break when executed via ruby -e
|
283
|
+
* Make sure WEBrick respects the :Host option
|
284
|
+
* Many Ruby 1.9 fixes.
|
285
|
+
|
275
286
|
== Contact
|
276
287
|
|
277
288
|
Please mail bugs, suggestions and patches to
|
data/SPEC
CHANGED
@@ -92,7 +92,9 @@ There are the following restrictions:
|
|
92
92
|
<tt>SCRIPT_NAME</tt> never should be <tt>/</tt>, but instead be empty.
|
93
93
|
=== The Input Stream
|
94
94
|
The input stream is an IO-like object which contains the raw HTTP
|
95
|
-
POST data.
|
95
|
+
POST data.
|
96
|
+
When applicable, its external encoding must be "ASCII-8BIT" and it
|
97
|
+
must be opened in binary mode, for Ruby 1.9 compatibility.
|
96
98
|
The input stream must respond to +gets+, +each+, +read+ and +rewind+.
|
97
99
|
* +gets+ must be called without arguments and return a string,
|
98
100
|
or +nil+ on EOF.
|
data/lib/rack/deflater.rb
CHANGED
data/lib/rack/handler/cgi.rb
CHANGED
data/lib/rack/handler/fastcgi.rb
CHANGED
@@ -3,13 +3,15 @@ require 'socket'
|
|
3
3
|
require 'rack/content_length'
|
4
4
|
require 'rack/rewindable_input'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
if defined? FCGI::Stream
|
7
|
+
class FCGI::Stream
|
8
|
+
alias _rack_read_without_buffer read
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def read(n, buffer=nil)
|
11
|
+
buf = _rack_read_without_buffer n
|
12
|
+
buffer.replace(buf.to_s) if buffer
|
13
|
+
buf
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -34,7 +36,7 @@ module Rack
|
|
34
36
|
|
35
37
|
rack_input = RewindableInput.new(request.in)
|
36
38
|
|
37
|
-
env.update({"rack.version" => [0
|
39
|
+
env.update({"rack.version" => [1,0],
|
38
40
|
"rack.input" => rack_input,
|
39
41
|
"rack.errors" => request.err,
|
40
42
|
|
data/lib/rack/handler/lsws.rb
CHANGED
@@ -15,14 +15,19 @@ module Rack
|
|
15
15
|
env = ENV.to_hash
|
16
16
|
env.delete "HTTP_CONTENT_LENGTH"
|
17
17
|
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
|
19
|
+
rack_input = RewindableInput.new($stdin.read.to_s)
|
20
|
+
|
21
|
+
env.update(
|
22
|
+
"rack.version" => [1,0],
|
23
|
+
"rack.input" => rack_input,
|
24
|
+
"rack.errors" => $stderr,
|
25
|
+
"rack.multithread" => false,
|
26
|
+
"rack.multiprocess" => true,
|
27
|
+
"rack.run_once" => false,
|
28
|
+
"rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
|
29
|
+
)
|
30
|
+
|
26
31
|
env["QUERY_STRING"] ||= ""
|
27
32
|
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
28
33
|
env["REQUEST_PATH"] ||= "/"
|
data/lib/rack/handler/mongrel.rb
CHANGED
@@ -45,8 +45,11 @@ module Rack
|
|
45
45
|
|
46
46
|
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
rack_input = request.body || StringIO.new('')
|
49
|
+
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
50
|
+
|
51
|
+
env.update({"rack.version" => [1,0],
|
52
|
+
"rack.input" => rack_input,
|
50
53
|
"rack.errors" => $stderr,
|
51
54
|
|
52
55
|
"rack.multithread" => true,
|
data/lib/rack/handler/scgi.rb
CHANGED
@@ -32,10 +32,13 @@ module Rack
|
|
32
32
|
env["PATH_INFO"] = env["REQUEST_PATH"]
|
33
33
|
env["QUERY_STRING"] ||= ""
|
34
34
|
env["SCRIPT_NAME"] = ""
|
35
|
-
env.update({"rack.version" => [0,1],
|
36
|
-
"rack.input" => StringIO.new(input_body),
|
37
|
-
"rack.errors" => $stderr,
|
38
35
|
|
36
|
+
rack_input = StringIO.new(input_body)
|
37
|
+
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
38
|
+
|
39
|
+
env.update({"rack.version" => [1,0],
|
40
|
+
"rack.input" => rack_input,
|
41
|
+
"rack.errors" => $stderr,
|
39
42
|
"rack.multithread" => true,
|
40
43
|
"rack.multiprocess" => true,
|
41
44
|
"rack.run_once" => false,
|
data/lib/rack/handler/webrick.rb
CHANGED
@@ -6,6 +6,7 @@ module Rack
|
|
6
6
|
module Handler
|
7
7
|
class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
|
8
8
|
def self.run(app, options={})
|
9
|
+
options[:BindAddress] = options.delete(:Host) if options[:Host]
|
9
10
|
server = ::WEBrick::HTTPServer.new(options)
|
10
11
|
server.mount "/", Rack::Handler::WEBrick, app
|
11
12
|
trap(:INT) { server.shutdown }
|
@@ -22,8 +23,11 @@ module Rack
|
|
22
23
|
env = req.meta_vars
|
23
24
|
env.delete_if { |k, v| v.nil? }
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
rack_input = StringIO.new(req.body.to_s)
|
27
|
+
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
28
|
+
|
29
|
+
env.update({"rack.version" => [1,0],
|
30
|
+
"rack.input" => rack_input,
|
27
31
|
"rack.errors" => $stderr,
|
28
32
|
|
29
33
|
"rack.multithread" => true,
|
data/lib/rack/lint.rb
CHANGED
@@ -233,8 +233,17 @@ module Rack
|
|
233
233
|
## === The Input Stream
|
234
234
|
##
|
235
235
|
## The input stream is an IO-like object which contains the raw HTTP
|
236
|
-
## POST data.
|
236
|
+
## POST data.
|
237
237
|
def check_input(input)
|
238
|
+
## When applicable, its external encoding must be "ASCII-8BIT" and it
|
239
|
+
## must be opened in binary mode, for Ruby 1.9 compatibility.
|
240
|
+
assert("rack.input #{input} does not have ASCII-8BIT as its external encoding") {
|
241
|
+
input.external_encoding.name == "ASCII-8BIT"
|
242
|
+
} if input.respond_to?(:external_encoding)
|
243
|
+
assert("rack.input #{input} is not opened in binary mode") {
|
244
|
+
input.binmode?
|
245
|
+
} if input.respond_to?(:binmode?)
|
246
|
+
|
238
247
|
## The input stream must respond to +gets+, +each+, +read+ and +rewind+.
|
239
248
|
[:gets, :each, :read, :rewind].each { |method|
|
240
249
|
assert("rack.input #{input} does not respond to ##{method}") {
|
data/lib/rack/mock.rb
CHANGED
@@ -40,7 +40,7 @@ module Rack
|
|
40
40
|
end
|
41
41
|
|
42
42
|
DEFAULT_ENV = {
|
43
|
-
"rack.version" => [0
|
43
|
+
"rack.version" => [1,0],
|
44
44
|
"rack.input" => StringIO.new,
|
45
45
|
"rack.errors" => StringIO.new,
|
46
46
|
"rack.multithread" => true,
|
@@ -92,11 +92,14 @@ module Rack
|
|
92
92
|
|
93
93
|
opts[:input] ||= ""
|
94
94
|
if String === opts[:input]
|
95
|
-
|
95
|
+
rack_input = StringIO.new(opts[:input])
|
96
96
|
else
|
97
|
-
|
97
|
+
rack_input = opts[:input]
|
98
98
|
end
|
99
99
|
|
100
|
+
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
101
|
+
env['rack.input'] = rack_input
|
102
|
+
|
100
103
|
env["CONTENT_LENGTH"] ||= env["rack.input"].length.to_s
|
101
104
|
|
102
105
|
opts.each { |field, value|
|
data/lib/rack/reloader.rb
CHANGED
@@ -70,7 +70,7 @@ module Rack
|
|
70
70
|
next if file =~ /\.(so|bundle)$/ # cannot reload compiled files
|
71
71
|
|
72
72
|
found, stat = figure_path(file, paths)
|
73
|
-
next unless found
|
73
|
+
next unless found && stat && mtime = stat.mtime
|
74
74
|
|
75
75
|
@cache[file] = found
|
76
76
|
|
@@ -87,7 +87,7 @@ module Rack
|
|
87
87
|
found, stat = safe_stat(found)
|
88
88
|
return found, stat if found
|
89
89
|
|
90
|
-
paths.
|
90
|
+
paths.find do |possible_path|
|
91
91
|
path = ::File.join(possible_path, file)
|
92
92
|
found, stat = safe_stat(path)
|
93
93
|
return ::File.expand_path(found), stat if found
|
data/lib/rack/request.rb
CHANGED
@@ -17,14 +17,6 @@ module Rack
|
|
17
17
|
# The environment of the request.
|
18
18
|
attr_reader :env
|
19
19
|
|
20
|
-
def self.new(env, *args)
|
21
|
-
if self == Rack::Request
|
22
|
-
env["rack.request"] ||= super
|
23
|
-
else
|
24
|
-
super
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
20
|
def initialize(env)
|
29
21
|
@env = env
|
30
22
|
end
|
@@ -73,7 +65,7 @@ module Rack
|
|
73
65
|
|
74
66
|
def host
|
75
67
|
# Remove port number.
|
76
|
-
(@env["HTTP_HOST"] || @env["SERVER_NAME"]).gsub(/:\d+\z/, '')
|
68
|
+
(@env["HTTP_HOST"] || @env["SERVER_NAME"]).to_s.gsub(/:\d+\z/, '')
|
77
69
|
end
|
78
70
|
|
79
71
|
def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
|
@@ -72,6 +72,8 @@ module Rack
|
|
72
72
|
# access it because we have the file handle open.
|
73
73
|
@rewindable_io = Tempfile.new('RackRewindableInput')
|
74
74
|
@rewindable_io.chmod(0000)
|
75
|
+
@rewindable_io.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding)
|
76
|
+
@rewindable_io.binmode
|
75
77
|
if filesystem_has_posix_semantics?
|
76
78
|
@rewindable_io.unlink
|
77
79
|
@unlinked = true
|
data/lib/rack/utils.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- encoding: binary -*-
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
require 'tempfile'
|
3
5
|
|
@@ -11,7 +13,7 @@ module Rack
|
|
11
13
|
# version since it's faster. (Stolen from Camping).
|
12
14
|
def escape(s)
|
13
15
|
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
|
14
|
-
'%'+$1.unpack('H2'
|
16
|
+
'%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
15
17
|
}.tr(' ', '+')
|
16
18
|
end
|
17
19
|
module_function :escape
|
@@ -24,16 +26,18 @@ module Rack
|
|
24
26
|
end
|
25
27
|
module_function :unescape
|
26
28
|
|
29
|
+
DEFAULT_SEP = /[&;] */n
|
30
|
+
|
27
31
|
# Stolen from Mongrel, with some small modifications:
|
28
32
|
# Parses a query string by breaking it up at the '&'
|
29
33
|
# and ';' characters. You can also use this to parse
|
30
34
|
# cookies by changing the characters used in the second
|
31
35
|
# parameter (which defaults to '&;').
|
32
|
-
def parse_query(qs, d =
|
36
|
+
def parse_query(qs, d = nil)
|
33
37
|
params = {}
|
34
38
|
|
35
|
-
(qs || '').split(/[#{d}] */n).each do |p|
|
36
|
-
k, v =
|
39
|
+
(qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
|
40
|
+
k, v = p.split('=', 2).map { |x| unescape(x) }
|
37
41
|
|
38
42
|
if cur = params[k]
|
39
43
|
if cur.class == Array
|
@@ -50,10 +54,10 @@ module Rack
|
|
50
54
|
end
|
51
55
|
module_function :parse_query
|
52
56
|
|
53
|
-
def parse_nested_query(qs, d =
|
57
|
+
def parse_nested_query(qs, d = nil)
|
54
58
|
params = {}
|
55
59
|
|
56
|
-
(qs || '').split(/[#{d}] */n).each do |p|
|
60
|
+
(qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
|
57
61
|
k, v = unescape(p).split('=', 2)
|
58
62
|
normalize_params(params, k, v)
|
59
63
|
end
|
@@ -63,7 +67,7 @@ module Rack
|
|
63
67
|
module_function :parse_nested_query
|
64
68
|
|
65
69
|
def normalize_params(params, name, v = nil)
|
66
|
-
name =~ %r([\[\]]*([^\[\]]+)\]*)
|
70
|
+
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
67
71
|
k = $1 || ''
|
68
72
|
after = $' || ''
|
69
73
|
|
@@ -99,7 +103,7 @@ module Rack
|
|
99
103
|
if v.class == Array
|
100
104
|
build_query(v.map { |x| [k, x] })
|
101
105
|
else
|
102
|
-
escape(k)
|
106
|
+
"#{escape(k)}=#{escape(v)}"
|
103
107
|
end
|
104
108
|
}.join("&")
|
105
109
|
end
|
@@ -304,7 +308,7 @@ module Rack
|
|
304
308
|
input = env['rack.input']
|
305
309
|
input.rewind
|
306
310
|
|
307
|
-
boundary_size = boundary
|
311
|
+
boundary_size = Utils.bytesize(boundary) + EOL.size
|
308
312
|
bufsize = 16384
|
309
313
|
|
310
314
|
content_length -= boundary_size
|
@@ -326,7 +330,7 @@ module Rack
|
|
326
330
|
head = buf.slice!(0, i+2) # First \r\n
|
327
331
|
buf.slice!(0, 2) # Second \r\n
|
328
332
|
|
329
|
-
filename = head[/Content-Disposition:.* filename="
|
333
|
+
filename = head[/Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni, 1]
|
330
334
|
content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
|
331
335
|
name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
|
332
336
|
|
data/rack.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{rack}
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Christian Neukirchen"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-10-18}
|
10
10
|
s.default_executable = %q{rackup}
|
11
11
|
s.description = %q{Rack provides minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call. Also see http://rack.rubyforge.org.}
|
12
12
|
s.email = %q{chneukirchen@gmail.com}
|
13
13
|
s.executables = ["rackup"]
|
14
14
|
s.extra_rdoc_files = ["README", "SPEC", "RDOX", "KNOWN-ISSUES"]
|
15
|
-
s.files = ["COPYING", "KNOWN-ISSUES", "README", "Rakefile", "bin/rackup", "contrib/rack_logo.svg", "example/lobster.ru", "example/protectedlobster.rb", "example/protectedlobster.ru", "lib/rack.rb", "lib/rack/adapter/camping.rb", "lib/rack/auth/abstract/handler.rb", "lib/rack/auth/abstract/request.rb", "lib/rack/auth/basic.rb", "lib/rack/auth/digest/md5.rb", "lib/rack/auth/digest/nonce.rb", "lib/rack/auth/digest/params.rb", "lib/rack/auth/digest/request.rb", "lib/rack/auth/openid.rb", "lib/rack/builder.rb", "lib/rack/cascade.rb", "lib/rack/chunked.rb", "lib/rack/commonlogger.rb", "lib/rack/conditionalget.rb", "lib/rack/content_length.rb", "lib/rack/content_type.rb", "lib/rack/deflater.rb", "lib/rack/directory.rb", "lib/rack/file.rb", "lib/rack/handler.rb", "lib/rack/handler/cgi.rb", "lib/rack/handler/evented_mongrel.rb", "lib/rack/handler/fastcgi.rb", "lib/rack/handler/lsws.rb", "lib/rack/handler/mongrel.rb", "lib/rack/handler/scgi.rb", "lib/rack/handler/swiftiplied_mongrel.rb", "lib/rack/handler/thin.rb", "lib/rack/handler/webrick.rb", "lib/rack/head.rb", "lib/rack/lint.rb", "lib/rack/lobster.rb", "lib/rack/lock.rb", "lib/rack/methodoverride.rb", "lib/rack/mime.rb", "lib/rack/mock.rb", "lib/rack/recursive.rb", "lib/rack/reloader.rb", "lib/rack/request.rb", "lib/rack/response.rb", "lib/rack/rewindable_input.rb", "lib/rack/session/abstract/id.rb", "lib/rack/session/cookie.rb", "lib/rack/session/memcache.rb", "lib/rack/session/pool.rb", "lib/rack/showexceptions.rb", "lib/rack/showstatus.rb", "lib/rack/static.rb", "lib/rack/urlmap.rb", "lib/rack/utils.rb", "test/cgi/lighttpd.conf", "test/cgi/test", "test/cgi/test.fcgi", "test/cgi/test.ru", "test/multipart/binary", "test/multipart/empty", "test/multipart/ie", "test/multipart/nested", "test/multipart/none", "test/multipart/text", "test/spec_rack_auth_basic.rb", "test/spec_rack_auth_digest.rb", "test/spec_rack_auth_openid.rb", "test/spec_rack_builder.rb", "test/spec_rack_camping.rb", "test/spec_rack_cascade.rb", "test/spec_rack_cgi.rb", "test/spec_rack_chunked.rb", "test/spec_rack_commonlogger.rb", "test/spec_rack_conditionalget.rb", "test/spec_rack_content_length.rb", "test/spec_rack_content_type.rb", "test/spec_rack_deflater.rb", "test/spec_rack_directory.rb", "test/spec_rack_fastcgi.rb", "test/spec_rack_file.rb", "test/spec_rack_handler.rb", "test/spec_rack_head.rb", "test/spec_rack_lint.rb", "test/spec_rack_lobster.rb", "test/spec_rack_lock.rb", "test/spec_rack_methodoverride.rb", "test/spec_rack_mock.rb", "test/spec_rack_mongrel.rb", "test/spec_rack_recursive.rb", "test/spec_rack_request.rb", "test/spec_rack_response.rb", "test/spec_rack_rewindable_input.rb", "test/spec_rack_session_cookie.rb", "test/spec_rack_session_memcache.rb", "test/spec_rack_session_pool.rb", "test/spec_rack_showexceptions.rb", "test/spec_rack_showstatus.rb", "test/spec_rack_static.rb", "test/spec_rack_thin.rb", "test/spec_rack_urlmap.rb", "test/spec_rack_utils.rb", "test/spec_rack_webrick.rb", "test/testrequest.rb", "test/unregistered_handler/rack/handler/unregistered.rb", "test/unregistered_handler/rack/handler/unregistered_long_one.rb", "SPEC", "RDOX", "rack.gemspec"]
|
15
|
+
s.files = ["COPYING", "KNOWN-ISSUES", "README", "Rakefile", "bin/rackup", "contrib/rack_logo.svg", "example/lobster.ru", "example/protectedlobster.rb", "example/protectedlobster.ru", "lib/rack.rb", "lib/rack/adapter/camping.rb", "lib/rack/auth/abstract/handler.rb", "lib/rack/auth/abstract/request.rb", "lib/rack/auth/basic.rb", "lib/rack/auth/digest/md5.rb", "lib/rack/auth/digest/nonce.rb", "lib/rack/auth/digest/params.rb", "lib/rack/auth/digest/request.rb", "lib/rack/auth/openid.rb", "lib/rack/builder.rb", "lib/rack/cascade.rb", "lib/rack/chunked.rb", "lib/rack/commonlogger.rb", "lib/rack/conditionalget.rb", "lib/rack/content_length.rb", "lib/rack/content_type.rb", "lib/rack/deflater.rb", "lib/rack/directory.rb", "lib/rack/file.rb", "lib/rack/handler.rb", "lib/rack/handler/cgi.rb", "lib/rack/handler/evented_mongrel.rb", "lib/rack/handler/fastcgi.rb", "lib/rack/handler/lsws.rb", "lib/rack/handler/mongrel.rb", "lib/rack/handler/scgi.rb", "lib/rack/handler/swiftiplied_mongrel.rb", "lib/rack/handler/thin.rb", "lib/rack/handler/webrick.rb", "lib/rack/head.rb", "lib/rack/lint.rb", "lib/rack/lobster.rb", "lib/rack/lock.rb", "lib/rack/methodoverride.rb", "lib/rack/mime.rb", "lib/rack/mock.rb", "lib/rack/recursive.rb", "lib/rack/reloader.rb", "lib/rack/request.rb", "lib/rack/response.rb", "lib/rack/rewindable_input.rb", "lib/rack/session/abstract/id.rb", "lib/rack/session/cookie.rb", "lib/rack/session/memcache.rb", "lib/rack/session/pool.rb", "lib/rack/showexceptions.rb", "lib/rack/showstatus.rb", "lib/rack/static.rb", "lib/rack/urlmap.rb", "lib/rack/utils.rb", "test/cgi/lighttpd.conf", "test/cgi/test", "test/cgi/test.fcgi", "test/cgi/test.ru", "test/multipart/binary", "test/multipart/empty", "test/multipart/ie", "test/multipart/nested", "test/multipart/none", "test/multipart/semicolon", "test/multipart/text", "test/spec_rack_auth_basic.rb", "test/spec_rack_auth_digest.rb", "test/spec_rack_auth_openid.rb", "test/spec_rack_builder.rb", "test/spec_rack_camping.rb", "test/spec_rack_cascade.rb", "test/spec_rack_cgi.rb", "test/spec_rack_chunked.rb", "test/spec_rack_commonlogger.rb", "test/spec_rack_conditionalget.rb", "test/spec_rack_content_length.rb", "test/spec_rack_content_type.rb", "test/spec_rack_deflater.rb", "test/spec_rack_directory.rb", "test/spec_rack_fastcgi.rb", "test/spec_rack_file.rb", "test/spec_rack_handler.rb", "test/spec_rack_head.rb", "test/spec_rack_lint.rb", "test/spec_rack_lobster.rb", "test/spec_rack_lock.rb", "test/spec_rack_methodoverride.rb", "test/spec_rack_mock.rb", "test/spec_rack_mongrel.rb", "test/spec_rack_recursive.rb", "test/spec_rack_request.rb", "test/spec_rack_response.rb", "test/spec_rack_rewindable_input.rb", "test/spec_rack_session_cookie.rb", "test/spec_rack_session_memcache.rb", "test/spec_rack_session_pool.rb", "test/spec_rack_showexceptions.rb", "test/spec_rack_showstatus.rb", "test/spec_rack_static.rb", "test/spec_rack_thin.rb", "test/spec_rack_urlmap.rb", "test/spec_rack_utils.rb", "test/spec_rack_webrick.rb", "test/testrequest.rb", "test/unregistered_handler/rack/handler/unregistered.rb", "test/unregistered_handler/rack/handler/unregistered_long_one.rb", "SPEC", "RDOX", "rack.gemspec"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{http://rack.rubyforge.org}
|
18
18
|
s.require_paths = ["lib"]
|
data/test/spec_rack_cgi.rb
CHANGED
@@ -36,7 +36,7 @@ context "Rack::Handler::CGI" do
|
|
36
36
|
|
37
37
|
specify "should have rack headers" do
|
38
38
|
GET("/test")
|
39
|
-
response["rack.version"].should.equal [0
|
39
|
+
response["rack.version"].should.equal [1,0]
|
40
40
|
response["rack.multithread"].should.be false
|
41
41
|
response["rack.multiprocess"].should.be true
|
42
42
|
response["rack.run_once"].should.be true
|
data/test/spec_rack_fastcgi.rb
CHANGED
@@ -36,7 +36,7 @@ context "Rack::Handler::FastCGI" do
|
|
36
36
|
|
37
37
|
specify "should have rack headers" do
|
38
38
|
GET("/test.fcgi")
|
39
|
-
response["rack.version"].should.equal [0
|
39
|
+
response["rack.version"].should.equal [1,0]
|
40
40
|
response["rack.multithread"].should.be false
|
41
41
|
response["rack.multiprocess"].should.be true
|
42
42
|
response["rack.run_once"].should.be false
|
data/test/spec_rack_lint.rb
CHANGED
@@ -110,6 +110,28 @@ context "Rack::Lint" do
|
|
110
110
|
Rack::Lint.new(nil).call(env("rack.input" => ""))
|
111
111
|
}.should.raise(Rack::Lint::LintError).
|
112
112
|
message.should.match(/does not respond to #gets/)
|
113
|
+
|
114
|
+
lambda {
|
115
|
+
input = Object.new
|
116
|
+
def input.binmode?
|
117
|
+
false
|
118
|
+
end
|
119
|
+
Rack::Lint.new(nil).call(env("rack.input" => input))
|
120
|
+
}.should.raise(Rack::Lint::LintError).
|
121
|
+
message.should.match(/is not opened in binary mode/)
|
122
|
+
|
123
|
+
lambda {
|
124
|
+
input = Object.new
|
125
|
+
def input.external_encoding
|
126
|
+
result = Object.new
|
127
|
+
def result.name
|
128
|
+
"US-ASCII"
|
129
|
+
end
|
130
|
+
result
|
131
|
+
end
|
132
|
+
Rack::Lint.new(nil).call(env("rack.input" => input))
|
133
|
+
}.should.raise(Rack::Lint::LintError).
|
134
|
+
message.should.match(/does not have ASCII-8BIT as its external encoding/)
|
113
135
|
end
|
114
136
|
|
115
137
|
specify "notices error errors" do
|
data/test/spec_rack_mock.rb
CHANGED
@@ -130,7 +130,7 @@ context "Rack::MockResponse" do
|
|
130
130
|
res.original_headers["Content-Type"].should.equal "text/yaml"
|
131
131
|
res["Content-Type"].should.equal "text/yaml"
|
132
132
|
res.content_type.should.equal "text/yaml"
|
133
|
-
res.content_length.should.be
|
133
|
+
res.content_length.should.be 401 # needs change often.
|
134
134
|
res.location.should.be.nil
|
135
135
|
end
|
136
136
|
|
data/test/spec_rack_mongrel.rb
CHANGED
@@ -41,7 +41,7 @@ context "Rack::Handler::Mongrel" do
|
|
41
41
|
|
42
42
|
specify "should have rack headers" do
|
43
43
|
GET("/test")
|
44
|
-
response["rack.version"].should.equal [0
|
44
|
+
response["rack.version"].should.equal [1,0]
|
45
45
|
response["rack.multithread"].should.be true
|
46
46
|
response["rack.multiprocess"].should.be false
|
47
47
|
response["rack.run_once"].should.be false
|
data/test/spec_rack_request.rb
CHANGED
@@ -37,6 +37,11 @@ context "Rack::Request" do
|
|
37
37
|
req = Rack::Request.new \
|
38
38
|
Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org:9292")
|
39
39
|
req.host.should.equal "example.org"
|
40
|
+
|
41
|
+
env = Rack::MockRequest.env_for("/")
|
42
|
+
env.delete("SERVER_NAME")
|
43
|
+
req = Rack::Request.new(env)
|
44
|
+
req.host.should.equal ""
|
40
45
|
end
|
41
46
|
|
42
47
|
specify "can parse the query string" do
|
@@ -467,22 +472,6 @@ EOF
|
|
467
472
|
res.body.should.equal '212.212.212.212'
|
468
473
|
end
|
469
474
|
|
470
|
-
specify "memoizes itself to reduce the cost of repetitive initialization" do
|
471
|
-
env = Rack::MockRequest.env_for("http://example.com:8080/")
|
472
|
-
env['rack.request'].should.be.nil
|
473
|
-
|
474
|
-
req1 = Rack::Request.new(env)
|
475
|
-
env['rack.request'].should.not.be.nil
|
476
|
-
req1.should.equal env['rack.request']
|
477
|
-
|
478
|
-
rack_request_object_id = env['rack.request'].object_id
|
479
|
-
|
480
|
-
req2 = Rack::Request.new(env)
|
481
|
-
env['rack.request'].should.not.be.nil
|
482
|
-
rack_request_object_id.should.be.equal env['rack.request'].object_id
|
483
|
-
req2.should.equal env['rack.request']
|
484
|
-
end
|
485
|
-
|
486
475
|
class MyRequest < Rack::Request
|
487
476
|
def params
|
488
477
|
{:foo => "bar"}
|
data/test/spec_rack_utils.rb
CHANGED
@@ -12,6 +12,15 @@ context "Rack::Utils" do
|
|
12
12
|
should.equal "q1%212%22%27w%245%267%2Fz8%29%3F%5C"
|
13
13
|
end
|
14
14
|
|
15
|
+
specify "should escape correctly for multibyte characters" do
|
16
|
+
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
17
|
+
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
18
|
+
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
19
|
+
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
20
|
+
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
21
|
+
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
22
|
+
end
|
23
|
+
|
15
24
|
specify "should unescape correctly" do
|
16
25
|
Rack::Utils.unescape("fo%3Co%3Ebar").should.equal "fo<o>bar"
|
17
26
|
Rack::Utils.unescape("a+space").should.equal "a space"
|
@@ -28,6 +37,7 @@ context "Rack::Utils" do
|
|
28
37
|
should.equal "foo" => "1", "bar" => "2"
|
29
38
|
Rack::Utils.parse_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
30
39
|
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
40
|
+
Rack::Utils.parse_query("foo%3Dbaz=bar").should.equal "foo=baz" => "bar"
|
31
41
|
end
|
32
42
|
|
33
43
|
specify "should parse nested query strings correctly" do
|
@@ -180,6 +190,30 @@ context "Rack::Utils::HeaderHash" do
|
|
180
190
|
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
181
191
|
h.to_hash.should.equal({ "foo" => "bar\nbaz" })
|
182
192
|
end
|
193
|
+
|
194
|
+
specify "should be able to delete the given key case-sensitively" do
|
195
|
+
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
196
|
+
h.delete("foo")
|
197
|
+
h["foo"].should.be.nil
|
198
|
+
h["FOO"].should.be.nil
|
199
|
+
end
|
200
|
+
|
201
|
+
specify "should be able to delete the given key case-insensitively" do
|
202
|
+
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
203
|
+
h.delete("FOO")
|
204
|
+
h["foo"].should.be.nil
|
205
|
+
h["FOO"].should.be.nil
|
206
|
+
end
|
207
|
+
|
208
|
+
specify "should return the deleted value when #delete is called on an existing key" do
|
209
|
+
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
210
|
+
h.delete("Foo").should.equal("bar")
|
211
|
+
end
|
212
|
+
|
213
|
+
specify "should return nil when #delete is called on a non-existant key" do
|
214
|
+
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
215
|
+
h.delete("Hello").should.be.nil
|
216
|
+
end
|
183
217
|
end
|
184
218
|
|
185
219
|
context "Rack::Utils::Context" do
|
@@ -295,6 +329,18 @@ context "Rack::Utils::Multipart" do
|
|
295
329
|
params["files"][:tempfile].read.should.equal ""
|
296
330
|
end
|
297
331
|
|
332
|
+
specify "should parse multipart upload with filename with semicolons" do
|
333
|
+
env = Rack::MockRequest.env_for("/", multipart_fixture(:semicolon))
|
334
|
+
params = Rack::Utils::Multipart.parse_multipart(env)
|
335
|
+
params["files"][:type].should.equal "text/plain"
|
336
|
+
params["files"][:filename].should.equal "fi;le1.txt"
|
337
|
+
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
338
|
+
"name=\"files\"; filename=\"fi;le1.txt\"\r\n" +
|
339
|
+
"Content-Type: text/plain\r\n"
|
340
|
+
params["files"][:name].should.equal "files"
|
341
|
+
params["files"][:tempfile].read.should.equal "contents"
|
342
|
+
end
|
343
|
+
|
298
344
|
specify "should not include file params if no file was selected" do
|
299
345
|
env = Rack::MockRequest.env_for("/", multipart_fixture(:none))
|
300
346
|
params = Rack::Utils::Multipart.parse_multipart(env)
|
data/test/spec_rack_webrick.rb
CHANGED
@@ -39,7 +39,7 @@ context "Rack::Handler::WEBrick" do
|
|
39
39
|
|
40
40
|
specify "should have rack headers" do
|
41
41
|
GET("/test")
|
42
|
-
response["rack.version"].should.equal [0
|
42
|
+
response["rack.version"].should.equal [1,0]
|
43
43
|
response["rack.multithread"].should.be true
|
44
44
|
response["rack.multiprocess"].should.be false
|
45
45
|
response["rack.run_once"].should.be false
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Neukirchen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-18 00:00:00 +02:00
|
13
13
|
default_executable: rackup
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -163,6 +163,7 @@ files:
|
|
163
163
|
- test/multipart/ie
|
164
164
|
- test/multipart/nested
|
165
165
|
- test/multipart/none
|
166
|
+
- test/multipart/semicolon
|
166
167
|
- test/multipart/text
|
167
168
|
- test/spec_rack_auth_basic.rb
|
168
169
|
- test/spec_rack_auth_digest.rb
|