rack 0.4.0 → 0.9.0

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.

Files changed (59) hide show
  1. data/RDOX +61 -3
  2. data/README +52 -37
  3. data/Rakefile +9 -0
  4. data/SPEC +6 -3
  5. data/bin/rackup +0 -0
  6. data/lib/rack.rb +7 -2
  7. data/lib/rack/adapter/camping.rb +1 -1
  8. data/lib/rack/auth/openid.rb +4 -3
  9. data/lib/rack/builder.rb +12 -1
  10. data/lib/rack/conditionalget.rb +43 -0
  11. data/lib/rack/content_length.rb +25 -0
  12. data/lib/rack/deflater.rb +29 -5
  13. data/lib/rack/directory.rb +82 -91
  14. data/lib/rack/file.rb +45 -76
  15. data/lib/rack/handler.rb +4 -0
  16. data/lib/rack/handler/evented_mongrel.rb +1 -1
  17. data/lib/rack/handler/fastcgi.rb +2 -0
  18. data/lib/rack/handler/mongrel.rb +6 -2
  19. data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  20. data/lib/rack/handler/thin.rb +15 -0
  21. data/lib/rack/handler/webrick.rb +8 -4
  22. data/lib/rack/head.rb +19 -0
  23. data/lib/rack/lint.rb +74 -10
  24. data/lib/rack/lobster.rb +13 -13
  25. data/lib/rack/methodoverride.rb +27 -0
  26. data/lib/rack/mime.rb +204 -0
  27. data/lib/rack/request.rb +10 -1
  28. data/lib/rack/response.rb +7 -2
  29. data/lib/rack/session/abstract/id.rb +14 -1
  30. data/lib/rack/session/cookie.rb +19 -1
  31. data/lib/rack/session/memcache.rb +1 -1
  32. data/lib/rack/session/pool.rb +1 -1
  33. data/lib/rack/showexceptions.rb +5 -1
  34. data/lib/rack/showstatus.rb +3 -2
  35. data/lib/rack/urlmap.rb +1 -1
  36. data/lib/rack/utils.rb +42 -13
  37. data/test/cgi/lighttpd.conf +1 -1
  38. data/test/cgi/test +0 -0
  39. data/test/cgi/test.fcgi +0 -0
  40. data/test/cgi/test.ru +0 -0
  41. data/test/spec_rack_builder.rb +34 -0
  42. data/test/spec_rack_conditionalget.rb +41 -0
  43. data/test/spec_rack_content_length.rb +43 -0
  44. data/test/spec_rack_deflater.rb +49 -14
  45. data/test/spec_rack_file.rb +7 -0
  46. data/test/spec_rack_handler.rb +3 -3
  47. data/test/spec_rack_head.rb +30 -0
  48. data/test/spec_rack_lint.rb +79 -2
  49. data/test/spec_rack_methodoverride.rb +60 -0
  50. data/test/spec_rack_mock.rb +1 -1
  51. data/test/spec_rack_mongrel.rb +20 -1
  52. data/test/spec_rack_request.rb +46 -1
  53. data/test/spec_rack_response.rb +10 -3
  54. data/test/spec_rack_session_cookie.rb +33 -0
  55. data/test/spec_rack_thin.rb +90 -0
  56. data/test/spec_rack_utils.rb +20 -18
  57. data/test/spec_rack_webrick.rb +17 -0
  58. data/test/testrequest.rb +12 -0
  59. metadata +91 -5
@@ -1,4 +1,5 @@
1
1
  require 'test/spec'
2
+ require 'set'
2
3
 
3
4
  require 'rack/response'
4
5
 
@@ -7,7 +8,7 @@ context "Rack::Response" do
7
8
  response = Rack::Response.new
8
9
  status, header, body = response.finish
9
10
  status.should.equal 200
10
- header.should.equal "Content-Type" => "text/html"
11
+ header.should.equal "Content-Type" => "text/html", "Content-Length" => "0"
11
12
  body.each { |part|
12
13
  part.should.equal ""
13
14
  }
@@ -15,7 +16,7 @@ context "Rack::Response" do
15
16
  response = Rack::Response.new
16
17
  status, header, body = *response
17
18
  status.should.equal 200
18
- header.should.equal "Content-Type" => "text/html"
19
+ header.should.equal "Content-Type" => "text/html", "Content-Length" => "0"
19
20
  body.each { |part|
20
21
  part.should.equal ""
21
22
  }
@@ -62,6 +63,12 @@ context "Rack::Response" do
62
63
  /expires=..., \d\d-...-\d\d\d\d \d\d:\d\d:\d\d .../)
63
64
  end
64
65
 
66
+ specify "can set secure cookies" do
67
+ response = Rack::Response.new
68
+ response.set_cookie "foo", {:value => "bar", :secure => true}
69
+ response["Set-Cookie"].should.equal "foo=bar; secure"
70
+ end
71
+
65
72
  specify "can delete cookies" do
66
73
  response = Rack::Response.new
67
74
  response.set_cookie "foo", "bar"
@@ -82,7 +89,7 @@ context "Rack::Response" do
82
89
  str = ""; body.each { |part| str << part }
83
90
  str.should.equal "foobar"
84
91
 
85
- r = Rack::Response.new({"foo", "bar"})
92
+ r = Rack::Response.new(["foo", "bar"].to_set)
86
93
  r.write "foo"
87
94
  status, header, body = r.finish
88
95
  str = ""; body.each { |part| str << part }
@@ -46,4 +46,37 @@ context "Rack::Session::Cookie" do
46
46
  get("/", :fatal => true)
47
47
  }.should.raise(Rack::MockRequest::FatalWarning)
48
48
  end
49
+
50
+ specify "creates a new cookie with integrity hash" do
51
+ res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).get("/")
52
+ if RUBY_VERSION < "1.9"
53
+ res["Set-Cookie"].should.match("rack.session=BAh7BiIMY291bnRlcmkG%0A--1439b4d37b9d4b04c603848382f712d6fcd31088")
54
+ else
55
+ res["Set-Cookie"].should.match("rack.session=BAh7BkkiDGNvdW50ZXIGOg1lbmNvZGluZyINVVMtQVNDSUlpBg%3D%3D%0A--d7a6637b94d2728194a96c18484e1f7ed9074a83")
56
+ end
57
+ end
58
+
59
+ specify "loads from a cookie wih integrity hash" do
60
+ res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).get("/")
61
+ cookie = res["Set-Cookie"]
62
+ res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
63
+ get("/", "HTTP_COOKIE" => cookie)
64
+ res.body.should.equal '{"counter"=>2}'
65
+ cookie = res["Set-Cookie"]
66
+ res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
67
+ get("/", "HTTP_COOKIE" => cookie)
68
+ res.body.should.equal '{"counter"=>3}'
69
+ end
70
+
71
+ specify "ignores tampered with session cookies" do
72
+ app = Rack::Session::Cookie.new(incrementor, :secret => 'test')
73
+ response1 = Rack::MockRequest.new(app).get("/")
74
+ _, digest = response1["Set-Cookie"].split("--")
75
+ tampered_with_cookie = "hackerman-was-here" + "--" + digest
76
+ response2 = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" =>
77
+ tampered_with_cookie)
78
+
79
+ # The tampered-with cookie is ignored, so we get back an identical Set-Cookie
80
+ response2["Set-Cookie"].should.equal(response1["Set-Cookie"])
81
+ end
49
82
  end
@@ -0,0 +1,90 @@
1
+ require 'test/spec'
2
+
3
+ begin
4
+ require 'rack/handler/thin'
5
+ require 'testrequest'
6
+ require 'timeout'
7
+
8
+ context "Rack::Handler::Thin" do
9
+ include TestRequest::Helpers
10
+
11
+ setup do
12
+ @app = Rack::Lint.new(TestRequest.new)
13
+ Thin::Logging.silent = true
14
+ @thread = Thread.new do
15
+ Rack::Handler::Thin.run(@app, :Host => @host='0.0.0.0', :Port => @port=9201) do |server|
16
+ @server = server
17
+ end
18
+ end
19
+ Thread.pass until @server && @server.running?
20
+ end
21
+
22
+ specify "should respond" do
23
+ lambda {
24
+ GET("/")
25
+ }.should.not.raise
26
+ end
27
+
28
+ specify "should be a Thin" do
29
+ GET("/")
30
+ status.should.be 200
31
+ response["SERVER_SOFTWARE"].should =~ /thin/
32
+ response["HTTP_VERSION"].should.equal "HTTP/1.1"
33
+ response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
34
+ response["SERVER_PORT"].should.equal "9201"
35
+ response["SERVER_NAME"].should.equal "0.0.0.0"
36
+ end
37
+
38
+ specify "should have rack headers" do
39
+ GET("/")
40
+ response["rack.version"].should.equal [0,3]
41
+ response["rack.multithread"].should.be false
42
+ response["rack.multiprocess"].should.be false
43
+ response["rack.run_once"].should.be false
44
+ end
45
+
46
+ specify "should have CGI headers on GET" do
47
+ GET("/")
48
+ response["REQUEST_METHOD"].should.equal "GET"
49
+ response["REQUEST_PATH"].should.equal "/"
50
+ response["PATH_INFO"].should.be.equal "/"
51
+ response["QUERY_STRING"].should.equal ""
52
+ response["test.postdata"].should.equal ""
53
+
54
+ GET("/test/foo?quux=1")
55
+ response["REQUEST_METHOD"].should.equal "GET"
56
+ response["REQUEST_PATH"].should.equal "/test/foo"
57
+ response["PATH_INFO"].should.equal "/test/foo"
58
+ response["QUERY_STRING"].should.equal "quux=1"
59
+ end
60
+
61
+ specify "should have CGI headers on POST" do
62
+ POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
63
+ status.should.equal 200
64
+ response["REQUEST_METHOD"].should.equal "POST"
65
+ response["REQUEST_PATH"].should.equal "/"
66
+ response["QUERY_STRING"].should.equal ""
67
+ response["HTTP_X_TEST_HEADER"].should.equal "42"
68
+ response["test.postdata"].should.equal "rack-form-data=23"
69
+ end
70
+
71
+ specify "should support HTTP auth" do
72
+ GET("/test", {:user => "ruth", :passwd => "secret"})
73
+ response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
74
+ end
75
+
76
+ specify "should set status" do
77
+ GET("/test?secret")
78
+ status.should.equal 403
79
+ response["rack.url_scheme"].should.equal "http"
80
+ end
81
+
82
+ teardown do
83
+ @server.stop!
84
+ @thread.kill
85
+ end
86
+ end
87
+
88
+ rescue LoadError
89
+ $stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again."
90
+ end
@@ -65,28 +65,30 @@ context "Rack::Utils" do
65
65
  end
66
66
 
67
67
  context "Rack::Utils::HeaderHash" do
68
- specify "should capitalize on all accesses" do
69
- h = Rack::Utils::HeaderHash.new("foo" => "bar")
70
- h["foo"].should.equal "bar"
71
- h["Foo"].should.equal "bar"
72
- h["FOO"].should.equal "bar"
73
-
74
- h.to_hash.should.equal "Foo" => "bar"
75
-
76
- h["bar-zzle"] = "quux"
68
+ specify "should retain header case" do
69
+ h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
70
+ h['ETag'] = 'Boo!'
71
+ h.to_hash.should.equal "Content-MD5" => "d5ff4e2a0 ...", "ETag" => 'Boo!'
72
+ end
77
73
 
78
- h.to_hash.should.equal "Foo" => "bar", "Bar-Zzle" => "quux"
74
+ specify "should check existence of keys case insensitively" do
75
+ h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
76
+ h.should.include 'content-md5'
77
+ h.should.not.include 'ETag'
79
78
  end
80
79
 
81
- specify "should capitalize correctly" do
82
- h = Rack::Utils::HeaderHash.new
80
+ specify "should merge case-insensitively" do
81
+ h = Rack::Utils::HeaderHash.new("ETag" => 'HELLO', "content-length" => '123')
82
+ merged = h.merge("Etag" => 'WORLD', 'Content-Length' => '321', "Foo" => 'BAR')
83
+ merged.should.equal "Etag"=>'WORLD', "Content-Length"=>'321', "Foo"=>'BAR'
84
+ end
83
85
 
84
- h.capitalize("foo").should.equal "Foo"
85
- h.capitalize("foo-bar").should.equal "Foo-Bar"
86
- h.capitalize("foo_bar").should.equal "Foo_Bar"
87
- h.capitalize("foo bar").should.equal "Foo Bar"
88
- h.capitalize("foo-bar-quux").should.equal "Foo-Bar-Quux"
89
- h.capitalize("foo-bar-2quux").should.equal "Foo-Bar-2quux"
86
+ specify "should overwrite case insensitively and assume the new key's case" do
87
+ h = Rack::Utils::HeaderHash.new("Foo-Bar" => "baz")
88
+ h["foo-bar"] = "bizzle"
89
+ h["FOO-BAR"].should.equal "bizzle"
90
+ h.length.should.equal 1
91
+ h.to_hash.should.equal "foo-bar" => "bizzle"
90
92
  end
91
93
 
92
94
  specify "should be converted to real Hash" do
@@ -2,6 +2,7 @@ require 'test/spec'
2
2
 
3
3
  require 'rack/handler/webrick'
4
4
  require 'rack/lint'
5
+ require 'rack/response'
5
6
  require 'testrequest'
6
7
 
7
8
  Thread.abort_on_exception = true
@@ -83,6 +84,22 @@ context "Rack::Handler::WEBrick" do
83
84
  response["rack.url_scheme"].should.equal "http"
84
85
  end
85
86
 
87
+ specify "should correctly set cookies" do
88
+ @server.mount "/cookie-test", Rack::Handler::WEBrick,
89
+ Rack::Lint.new(lambda { |req|
90
+ res = Rack::Response.new
91
+ res.set_cookie "one", "1"
92
+ res.set_cookie "two", "2"
93
+ res.finish
94
+ })
95
+
96
+ Net::HTTP.start(@host, @port) { |http|
97
+ res = http.get("/cookie-test")
98
+ res.code.to_i.should.equal 200
99
+ res.get_fields("set-cookie").should.equal ["one=1", "two=2"]
100
+ }
101
+ end
102
+
86
103
  specify "should provide a .run" do
87
104
  block_ran = false
88
105
  catch(:done) {
data/test/testrequest.rb CHANGED
@@ -43,3 +43,15 @@ class TestRequest
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ class StreamingRequest
48
+ def self.call(env)
49
+ [200, {"Content-Type" => "text/plain"}, new]
50
+ end
51
+
52
+ def each
53
+ yield "hello there!\n"
54
+ sleep 5
55
+ yield "that is all.\n"
56
+ end
57
+ end
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: 0.4.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Neukirchen
@@ -9,10 +9,79 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-21 00:00:00 +02:00
12
+ date: 2009-01-06 00:00:00 +01:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: test-spec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: camping
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: fcgi
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: memcache-client
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongrel
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: ruby-openid
67
+ type: :development
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ version: 2.0.0
74
+ version:
75
+ - !ruby/object:Gem::Dependency
76
+ name: thin
77
+ type: :development
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
16
85
  description: 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.
17
86
  email: chneukirchen@gmail.com
18
87
  executables:
@@ -48,6 +117,8 @@ files:
48
117
  - lib/rack/builder.rb
49
118
  - lib/rack/cascade.rb
50
119
  - lib/rack/commonlogger.rb
120
+ - lib/rack/conditionalget.rb
121
+ - lib/rack/content_length.rb
51
122
  - lib/rack/deflater.rb
52
123
  - lib/rack/directory.rb
53
124
  - lib/rack/file.rb
@@ -58,9 +129,14 @@ files:
58
129
  - lib/rack/handler/lsws.rb
59
130
  - lib/rack/handler/mongrel.rb
60
131
  - lib/rack/handler/scgi.rb
132
+ - lib/rack/handler/swiftiplied_mongrel.rb
133
+ - lib/rack/handler/thin.rb
61
134
  - lib/rack/handler/webrick.rb
135
+ - lib/rack/head.rb
62
136
  - lib/rack/lint.rb
63
137
  - lib/rack/lobster.rb
138
+ - lib/rack/methodoverride.rb
139
+ - lib/rack/mime.rb
64
140
  - lib/rack/mock.rb
65
141
  - lib/rack/recursive.rb
66
142
  - lib/rack/reloader.rb
@@ -87,13 +163,17 @@ files:
87
163
  - test/spec_rack_cascade.rb
88
164
  - test/spec_rack_cgi.rb
89
165
  - test/spec_rack_commonlogger.rb
166
+ - test/spec_rack_conditionalget.rb
167
+ - test/spec_rack_content_length.rb
90
168
  - test/spec_rack_deflater.rb
91
169
  - test/spec_rack_directory.rb
92
170
  - test/spec_rack_fastcgi.rb
93
171
  - test/spec_rack_file.rb
94
172
  - test/spec_rack_handler.rb
173
+ - test/spec_rack_head.rb
95
174
  - test/spec_rack_lint.rb
96
175
  - test/spec_rack_lobster.rb
176
+ - test/spec_rack_methodoverride.rb
97
177
  - test/spec_rack_mock.rb
98
178
  - test/spec_rack_mongrel.rb
99
179
  - test/spec_rack_recursive.rb
@@ -105,6 +185,7 @@ files:
105
185
  - test/spec_rack_showexceptions.rb
106
186
  - test/spec_rack_showstatus.rb
107
187
  - test/spec_rack_static.rb
188
+ - test/spec_rack_thin.rb
108
189
  - test/spec_rack_urlmap.rb
109
190
  - test/spec_rack_utils.rb
110
191
  - test/spec_rack_webrick.rb
@@ -133,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
214
  requirements: []
134
215
 
135
216
  rubyforge_project: rack
136
- rubygems_version: 1.0.1
217
+ rubygems_version: 1.3.1
137
218
  signing_key:
138
219
  specification_version: 2
139
220
  summary: a modular Ruby webserver interface
@@ -146,13 +227,17 @@ test_files:
146
227
  - test/spec_rack_cascade.rb
147
228
  - test/spec_rack_cgi.rb
148
229
  - test/spec_rack_commonlogger.rb
230
+ - test/spec_rack_conditionalget.rb
231
+ - test/spec_rack_content_length.rb
149
232
  - test/spec_rack_deflater.rb
150
233
  - test/spec_rack_directory.rb
151
234
  - test/spec_rack_fastcgi.rb
152
235
  - test/spec_rack_file.rb
153
236
  - test/spec_rack_handler.rb
237
+ - test/spec_rack_head.rb
154
238
  - test/spec_rack_lint.rb
155
239
  - test/spec_rack_lobster.rb
240
+ - test/spec_rack_methodoverride.rb
156
241
  - test/spec_rack_mock.rb
157
242
  - test/spec_rack_mongrel.rb
158
243
  - test/spec_rack_recursive.rb
@@ -164,6 +249,7 @@ test_files:
164
249
  - test/spec_rack_showexceptions.rb
165
250
  - test/spec_rack_showstatus.rb
166
251
  - test/spec_rack_static.rb
252
+ - test/spec_rack_thin.rb
167
253
  - test/spec_rack_urlmap.rb
168
254
  - test/spec_rack_utils.rb
169
255
  - test/spec_rack_webrick.rb