rack 1.0.1 → 2.2.21

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.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +829 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +355 -0
  6. data/Rakefile +64 -98
  7. data/SPEC.rdoc +292 -0
  8. data/bin/rackup +3 -174
  9. data/contrib/rack.png +0 -0
  10. data/contrib/rack.svg +150 -0
  11. data/contrib/rack_logo.svg +164 -111
  12. data/contrib/rdoc.css +412 -0
  13. data/example/lobster.ru +2 -0
  14. data/example/protectedlobster.rb +4 -2
  15. data/example/protectedlobster.ru +3 -1
  16. data/lib/rack/auth/abstract/handler.rb +7 -5
  17. data/lib/rack/auth/abstract/request.rb +12 -2
  18. data/lib/rack/auth/basic.rb +6 -4
  19. data/lib/rack/auth/digest/md5.rb +20 -13
  20. data/lib/rack/auth/digest/nonce.rb +6 -4
  21. data/lib/rack/auth/digest/params.rb +11 -12
  22. data/lib/rack/auth/digest/request.rb +15 -12
  23. data/lib/rack/body_proxy.rb +45 -0
  24. data/lib/rack/builder.rb +213 -19
  25. data/lib/rack/cascade.rb +50 -18
  26. data/lib/rack/chunked.rb +95 -27
  27. data/lib/rack/common_logger.rb +84 -0
  28. data/lib/rack/conditional_get.rb +83 -0
  29. data/lib/rack/config.rb +22 -0
  30. data/lib/rack/content_length.rb +19 -10
  31. data/lib/rack/content_type.rb +12 -5
  32. data/lib/rack/core_ext/regexp.rb +14 -0
  33. data/lib/rack/deflater.rb +90 -42
  34. data/lib/rack/directory.rb +118 -72
  35. data/lib/rack/etag.rb +77 -0
  36. data/lib/rack/events.rb +153 -0
  37. data/lib/rack/file.rb +4 -85
  38. data/lib/rack/files.rb +218 -0
  39. data/lib/rack/handler/cgi.rb +22 -24
  40. data/lib/rack/handler/fastcgi.rb +34 -24
  41. data/lib/rack/handler/lsws.rb +16 -15
  42. data/lib/rack/handler/scgi.rb +38 -29
  43. data/lib/rack/handler/thin.rb +23 -7
  44. data/lib/rack/handler/webrick.rb +95 -37
  45. data/lib/rack/handler.rb +49 -14
  46. data/lib/rack/head.rb +19 -13
  47. data/lib/rack/lint.rb +466 -217
  48. data/lib/rack/lobster.rb +19 -14
  49. data/lib/rack/lock.rb +24 -8
  50. data/lib/rack/logger.rb +20 -0
  51. data/lib/rack/media_type.rb +53 -0
  52. data/lib/rack/method_override.rb +52 -0
  53. data/lib/rack/mime.rb +652 -171
  54. data/lib/rack/mock.rb +203 -64
  55. data/lib/rack/multipart/generator.rb +97 -0
  56. data/lib/rack/multipart/parser.rb +440 -0
  57. data/lib/rack/multipart/uploaded_file.rb +41 -0
  58. data/lib/rack/multipart.rb +64 -0
  59. data/lib/rack/null_logger.rb +39 -0
  60. data/lib/rack/query_parser.rb +266 -0
  61. data/lib/rack/recursive.rb +18 -11
  62. data/lib/rack/reloader.rb +13 -5
  63. data/lib/rack/request.rb +607 -191
  64. data/lib/rack/response.rb +245 -110
  65. data/lib/rack/rewindable_input.rb +15 -21
  66. data/lib/rack/runtime.rb +34 -0
  67. data/lib/rack/sendfile.rb +192 -0
  68. data/lib/rack/server.rb +466 -0
  69. data/lib/rack/session/abstract/id.rb +449 -68
  70. data/lib/rack/session/cookie.rb +159 -47
  71. data/lib/rack/session/memcache.rb +4 -103
  72. data/lib/rack/session/pool.rb +39 -49
  73. data/lib/rack/show_exceptions.rb +390 -0
  74. data/lib/rack/{showstatus.rb → show_status.rb} +21 -14
  75. data/lib/rack/static.rb +164 -14
  76. data/lib/rack/tempfile_reaper.rb +22 -0
  77. data/lib/rack/urlmap.rb +60 -18
  78. data/lib/rack/utils.rb +508 -277
  79. data/lib/rack/version.rb +29 -0
  80. data/lib/rack.rb +85 -34
  81. data/rack.gemspec +43 -51
  82. metadata +119 -207
  83. data/KNOWN-ISSUES +0 -18
  84. data/RDOX +0 -428
  85. data/README +0 -364
  86. data/SPEC +0 -164
  87. data/lib/rack/adapter/camping.rb +0 -22
  88. data/lib/rack/auth/openid.rb +0 -480
  89. data/lib/rack/commonlogger.rb +0 -61
  90. data/lib/rack/conditionalget.rb +0 -47
  91. data/lib/rack/handler/evented_mongrel.rb +0 -8
  92. data/lib/rack/handler/mongrel.rb +0 -87
  93. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  94. data/lib/rack/methodoverride.rb +0 -27
  95. data/lib/rack/showexceptions.rb +0 -349
  96. data/test/cgi/lighttpd.conf +0 -20
  97. data/test/cgi/test +0 -9
  98. data/test/cgi/test.fcgi +0 -8
  99. data/test/cgi/test.ru +0 -7
  100. data/test/multipart/binary +0 -0
  101. data/test/multipart/empty +0 -10
  102. data/test/multipart/ie +0 -6
  103. data/test/multipart/nested +0 -10
  104. data/test/multipart/none +0 -9
  105. data/test/multipart/semicolon +0 -6
  106. data/test/multipart/text +0 -10
  107. data/test/spec_rack_auth_basic.rb +0 -73
  108. data/test/spec_rack_auth_digest.rb +0 -226
  109. data/test/spec_rack_auth_openid.rb +0 -84
  110. data/test/spec_rack_builder.rb +0 -84
  111. data/test/spec_rack_camping.rb +0 -51
  112. data/test/spec_rack_cascade.rb +0 -50
  113. data/test/spec_rack_cgi.rb +0 -89
  114. data/test/spec_rack_chunked.rb +0 -62
  115. data/test/spec_rack_commonlogger.rb +0 -32
  116. data/test/spec_rack_conditionalget.rb +0 -41
  117. data/test/spec_rack_content_length.rb +0 -43
  118. data/test/spec_rack_content_type.rb +0 -30
  119. data/test/spec_rack_deflater.rb +0 -127
  120. data/test/spec_rack_directory.rb +0 -61
  121. data/test/spec_rack_fastcgi.rb +0 -89
  122. data/test/spec_rack_file.rb +0 -75
  123. data/test/spec_rack_handler.rb +0 -43
  124. data/test/spec_rack_head.rb +0 -30
  125. data/test/spec_rack_lint.rb +0 -521
  126. data/test/spec_rack_lobster.rb +0 -45
  127. data/test/spec_rack_lock.rb +0 -38
  128. data/test/spec_rack_methodoverride.rb +0 -60
  129. data/test/spec_rack_mock.rb +0 -157
  130. data/test/spec_rack_mongrel.rb +0 -189
  131. data/test/spec_rack_recursive.rb +0 -77
  132. data/test/spec_rack_request.rb +0 -504
  133. data/test/spec_rack_response.rb +0 -218
  134. data/test/spec_rack_rewindable_input.rb +0 -118
  135. data/test/spec_rack_session_cookie.rb +0 -82
  136. data/test/spec_rack_session_memcache.rb +0 -240
  137. data/test/spec_rack_session_pool.rb +0 -172
  138. data/test/spec_rack_showexceptions.rb +0 -21
  139. data/test/spec_rack_showstatus.rb +0 -72
  140. data/test/spec_rack_static.rb +0 -37
  141. data/test/spec_rack_thin.rb +0 -91
  142. data/test/spec_rack_urlmap.rb +0 -185
  143. data/test/spec_rack_utils.rb +0 -387
  144. data/test/spec_rack_webrick.rb +0 -130
  145. data/test/testrequest.rb +0 -57
  146. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  147. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,157 +0,0 @@
1
- require 'yaml'
2
- require 'rack/mock'
3
- require 'rack/request'
4
- require 'rack/response'
5
-
6
- app = lambda { |env|
7
- req = Rack::Request.new(env)
8
-
9
- env["mock.postdata"] = env["rack.input"].read
10
- if req.GET["error"]
11
- env["rack.errors"].puts req.GET["error"]
12
- env["rack.errors"].flush
13
- end
14
-
15
- Rack::Response.new(env.to_yaml,
16
- req.GET["status"] || 200,
17
- "Content-Type" => "text/yaml").finish
18
- }
19
-
20
- context "Rack::MockRequest" do
21
- specify "should return a MockResponse" do
22
- res = Rack::MockRequest.new(app).get("")
23
- res.should.be.kind_of Rack::MockResponse
24
- end
25
-
26
- specify "should be able to only return the environment" do
27
- env = Rack::MockRequest.env_for("")
28
- env.should.be.kind_of Hash
29
- env.should.include "rack.version"
30
- end
31
-
32
- specify "should provide sensible defaults" do
33
- res = Rack::MockRequest.new(app).request
34
-
35
- env = YAML.load(res.body)
36
- env["REQUEST_METHOD"].should.equal "GET"
37
- env["SERVER_NAME"].should.equal "example.org"
38
- env["SERVER_PORT"].should.equal "80"
39
- env["QUERY_STRING"].should.equal ""
40
- env["PATH_INFO"].should.equal "/"
41
- env["SCRIPT_NAME"].should.equal ""
42
- env["rack.url_scheme"].should.equal "http"
43
- env["mock.postdata"].should.be.empty
44
- end
45
-
46
- specify "should allow GET/POST/PUT/DELETE" do
47
- res = Rack::MockRequest.new(app).get("", :input => "foo")
48
- env = YAML.load(res.body)
49
- env["REQUEST_METHOD"].should.equal "GET"
50
-
51
- res = Rack::MockRequest.new(app).post("", :input => "foo")
52
- env = YAML.load(res.body)
53
- env["REQUEST_METHOD"].should.equal "POST"
54
-
55
- res = Rack::MockRequest.new(app).put("", :input => "foo")
56
- env = YAML.load(res.body)
57
- env["REQUEST_METHOD"].should.equal "PUT"
58
-
59
- res = Rack::MockRequest.new(app).delete("", :input => "foo")
60
- env = YAML.load(res.body)
61
- env["REQUEST_METHOD"].should.equal "DELETE"
62
-
63
- Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
64
- should.equal "OPTIONS"
65
- end
66
-
67
- specify "should set content length" do
68
- env = Rack::MockRequest.env_for("/", :input => "foo")
69
- env["CONTENT_LENGTH"].should.equal "3"
70
- end
71
-
72
- specify "should allow posting" do
73
- res = Rack::MockRequest.new(app).get("", :input => "foo")
74
- env = YAML.load(res.body)
75
- env["mock.postdata"].should.equal "foo"
76
-
77
- res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
78
- env = YAML.load(res.body)
79
- env["mock.postdata"].should.equal "foo"
80
- end
81
-
82
- specify "should use all parts of an URL" do
83
- res = Rack::MockRequest.new(app).
84
- get("https://bla.example.org:9292/meh/foo?bar")
85
- res.should.be.kind_of Rack::MockResponse
86
-
87
- env = YAML.load(res.body)
88
- env["REQUEST_METHOD"].should.equal "GET"
89
- env["SERVER_NAME"].should.equal "bla.example.org"
90
- env["SERVER_PORT"].should.equal "9292"
91
- env["QUERY_STRING"].should.equal "bar"
92
- env["PATH_INFO"].should.equal "/meh/foo"
93
- env["rack.url_scheme"].should.equal "https"
94
- end
95
-
96
- specify "should behave valid according to the Rack spec" do
97
- lambda {
98
- res = Rack::MockRequest.new(app).
99
- get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
100
- }.should.not.raise(Rack::Lint::LintError)
101
- end
102
- end
103
-
104
- context "Rack::MockResponse" do
105
- specify "should provide access to the HTTP status" do
106
- res = Rack::MockRequest.new(app).get("")
107
- res.should.be.successful
108
- res.should.be.ok
109
-
110
- res = Rack::MockRequest.new(app).get("/?status=404")
111
- res.should.not.be.successful
112
- res.should.be.client_error
113
- res.should.be.not_found
114
-
115
- res = Rack::MockRequest.new(app).get("/?status=501")
116
- res.should.not.be.successful
117
- res.should.be.server_error
118
-
119
- res = Rack::MockRequest.new(app).get("/?status=307")
120
- res.should.be.redirect
121
-
122
- res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
123
- res.should.be.empty
124
- end
125
-
126
- specify "should provide access to the HTTP headers" do
127
- res = Rack::MockRequest.new(app).get("")
128
- res.should.include "Content-Type"
129
- res.headers["Content-Type"].should.equal "text/yaml"
130
- res.original_headers["Content-Type"].should.equal "text/yaml"
131
- res["Content-Type"].should.equal "text/yaml"
132
- res.content_type.should.equal "text/yaml"
133
- res.content_length.should.be 401 # needs change often.
134
- res.location.should.be.nil
135
- end
136
-
137
- specify "should provide access to the HTTP body" do
138
- res = Rack::MockRequest.new(app).get("")
139
- res.body.should =~ /rack/
140
- res.should =~ /rack/
141
- res.should.match(/rack/)
142
- res.should.satisfy { |r| r.match(/rack/) }
143
- end
144
-
145
- specify "should provide access to the Rack errors" do
146
- res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
147
- res.should.be.ok
148
- res.errors.should.not.be.empty
149
- res.errors.should.include "foo"
150
- end
151
-
152
- specify "should optionally make Rack errors fatal" do
153
- lambda {
154
- Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
155
- }.should.raise(Rack::MockRequest::FatalWarning)
156
- end
157
- end
@@ -1,189 +0,0 @@
1
- require 'test/spec'
2
-
3
- begin
4
- require 'rack/handler/mongrel'
5
- require 'rack/urlmap'
6
- require 'rack/lint'
7
- require 'testrequest'
8
- require 'timeout'
9
-
10
- Thread.abort_on_exception = true
11
- $tcp_defer_accept_opts = nil
12
- $tcp_cork_opts = nil
13
-
14
- context "Rack::Handler::Mongrel" do
15
- include TestRequest::Helpers
16
-
17
- setup do
18
- server = Mongrel::HttpServer.new(@host='0.0.0.0', @port=9201)
19
- server.register('/test',
20
- Rack::Handler::Mongrel.new(Rack::Lint.new(TestRequest.new)))
21
- server.register('/stream',
22
- Rack::Handler::Mongrel.new(Rack::Lint.new(StreamingRequest)))
23
- @acc = server.run
24
- end
25
-
26
- specify "should respond" do
27
- lambda {
28
- GET("/test")
29
- }.should.not.raise
30
- end
31
-
32
- specify "should be a Mongrel" do
33
- GET("/test")
34
- status.should.be 200
35
- response["SERVER_SOFTWARE"].should =~ /Mongrel/
36
- response["HTTP_VERSION"].should.equal "HTTP/1.1"
37
- response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
38
- response["SERVER_PORT"].should.equal "9201"
39
- response["SERVER_NAME"].should.equal "0.0.0.0"
40
- end
41
-
42
- specify "should have rack headers" do
43
- GET("/test")
44
- response["rack.version"].should.equal [1,0]
45
- response["rack.multithread"].should.be true
46
- response["rack.multiprocess"].should.be false
47
- response["rack.run_once"].should.be false
48
- end
49
-
50
- specify "should have CGI headers on GET" do
51
- GET("/test")
52
- response["REQUEST_METHOD"].should.equal "GET"
53
- response["SCRIPT_NAME"].should.equal "/test"
54
- response["REQUEST_PATH"].should.equal "/test"
55
- response["PATH_INFO"].should.be.nil
56
- response["QUERY_STRING"].should.equal ""
57
- response["test.postdata"].should.equal ""
58
-
59
- GET("/test/foo?quux=1")
60
- response["REQUEST_METHOD"].should.equal "GET"
61
- response["SCRIPT_NAME"].should.equal "/test"
62
- response["REQUEST_PATH"].should.equal "/test/foo"
63
- response["PATH_INFO"].should.equal "/foo"
64
- response["QUERY_STRING"].should.equal "quux=1"
65
- end
66
-
67
- specify "should have CGI headers on POST" do
68
- POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
69
- status.should.equal 200
70
- response["REQUEST_METHOD"].should.equal "POST"
71
- response["SCRIPT_NAME"].should.equal "/test"
72
- response["REQUEST_PATH"].should.equal "/test"
73
- response["QUERY_STRING"].should.equal ""
74
- response["HTTP_X_TEST_HEADER"].should.equal "42"
75
- response["test.postdata"].should.equal "rack-form-data=23"
76
- end
77
-
78
- specify "should support HTTP auth" do
79
- GET("/test", {:user => "ruth", :passwd => "secret"})
80
- response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
81
- end
82
-
83
- specify "should set status" do
84
- GET("/test?secret")
85
- status.should.equal 403
86
- response["rack.url_scheme"].should.equal "http"
87
- end
88
-
89
- specify "should provide a .run" do
90
- block_ran = false
91
- Thread.new {
92
- Rack::Handler::Mongrel.run(lambda {}, {:Port => 9211}) { |server|
93
- server.should.be.kind_of Mongrel::HttpServer
94
- block_ran = true
95
- }
96
- }
97
- sleep 1
98
- block_ran.should.be true
99
- end
100
-
101
- specify "should provide a .run that maps a hash" do
102
- block_ran = false
103
- Thread.new {
104
- map = {'/'=>lambda{},'/foo'=>lambda{}}
105
- Rack::Handler::Mongrel.run(map, :map => true, :Port => 9221) { |server|
106
- server.should.be.kind_of Mongrel::HttpServer
107
- server.classifier.uris.size.should.be 2
108
- server.classifier.uris.should.not.include '/arf'
109
- server.classifier.uris.should.include '/'
110
- server.classifier.uris.should.include '/foo'
111
- block_ran = true
112
- }
113
- }
114
- sleep 1
115
- block_ran.should.be true
116
- end
117
-
118
- specify "should provide a .run that maps a urlmap" do
119
- block_ran = false
120
- Thread.new {
121
- map = Rack::URLMap.new({'/'=>lambda{},'/bar'=>lambda{}})
122
- Rack::Handler::Mongrel.run(map, {:map => true, :Port => 9231}) { |server|
123
- server.should.be.kind_of Mongrel::HttpServer
124
- server.classifier.uris.size.should.be 2
125
- server.classifier.uris.should.not.include '/arf'
126
- server.classifier.uris.should.include '/'
127
- server.classifier.uris.should.include '/bar'
128
- block_ran = true
129
- }
130
- }
131
- sleep 1
132
- block_ran.should.be true
133
- end
134
-
135
- specify "should provide a .run that maps a urlmap restricting by host" do
136
- block_ran = false
137
- Thread.new {
138
- map = Rack::URLMap.new({
139
- '/' => lambda{},
140
- '/foo' => lambda{},
141
- '/bar' => lambda{},
142
- 'http://localhost/' => lambda{},
143
- 'http://localhost/bar' => lambda{},
144
- 'http://falsehost/arf' => lambda{},
145
- 'http://falsehost/qux' => lambda{}
146
- })
147
- opt = {:map => true, :Port => 9241, :Host => 'localhost'}
148
- Rack::Handler::Mongrel.run(map, opt) { |server|
149
- server.should.be.kind_of Mongrel::HttpServer
150
- server.classifier.uris.should.include '/'
151
- server.classifier.handler_map['/'].size.should.be 2
152
- server.classifier.uris.should.include '/foo'
153
- server.classifier.handler_map['/foo'].size.should.be 1
154
- server.classifier.uris.should.include '/bar'
155
- server.classifier.handler_map['/bar'].size.should.be 2
156
- server.classifier.uris.should.not.include '/qux'
157
- server.classifier.uris.should.not.include '/arf'
158
- server.classifier.uris.size.should.be 3
159
- block_ran = true
160
- }
161
- }
162
- sleep 1
163
- block_ran.should.be true
164
- end
165
-
166
- specify "should stream #each part of the response" do
167
- body = ''
168
- begin
169
- Timeout.timeout(1) do
170
- Net::HTTP.start(@host, @port) do |http|
171
- get = Net::HTTP::Get.new('/stream')
172
- http.request(get) do |response|
173
- response.read_body { |part| body << part }
174
- end
175
- end
176
- end
177
- rescue Timeout::Error
178
- end
179
- body.should.not.be.empty
180
- end
181
-
182
- teardown do
183
- @acc.raise Mongrel::StopServer
184
- end
185
- end
186
-
187
- rescue LoadError
188
- $stderr.puts "Skipping Rack::Handler::Mongrel tests (Mongrel is required). `gem install mongrel` and try again."
189
- end
@@ -1,77 +0,0 @@
1
- require 'test/spec'
2
-
3
- require 'rack/recursive'
4
- require 'rack/urlmap'
5
- require 'rack/response'
6
- require 'rack/mock'
7
-
8
- context "Rack::Recursive" do
9
- setup do
10
-
11
- @app1 = lambda { |env|
12
- res = Rack::Response.new
13
- res["X-Path-Info"] = env["PATH_INFO"]
14
- res["X-Query-String"] = env["QUERY_STRING"]
15
- res.finish do |res|
16
- res.write "App1"
17
- end
18
- }
19
-
20
- @app2 = lambda { |env|
21
- Rack::Response.new.finish do |res|
22
- res.write "App2"
23
- _, _, body = env['rack.recursive.include'].call(env, "/app1")
24
- body.each { |b|
25
- res.write b
26
- }
27
- end
28
- }
29
-
30
- @app3 = lambda { |env|
31
- raise Rack::ForwardRequest.new("/app1")
32
- }
33
-
34
- @app4 = lambda { |env|
35
- raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
36
- }
37
-
38
- end
39
-
40
- specify "should allow for subrequests" do
41
- res = Rack::MockRequest.new(Rack::Recursive.new(
42
- Rack::URLMap.new("/app1" => @app1,
43
- "/app2" => @app2))).
44
- get("/app2")
45
-
46
- res.should.be.ok
47
- res.body.should.equal "App2App1"
48
- end
49
-
50
- specify "should raise error on requests not below the app" do
51
- app = Rack::URLMap.new("/app1" => @app1,
52
- "/app" => Rack::Recursive.new(
53
- Rack::URLMap.new("/1" => @app1,
54
- "/2" => @app2)))
55
-
56
- lambda {
57
- Rack::MockRequest.new(app).get("/app/2")
58
- }.should.raise(ArgumentError).
59
- message.should =~ /can only include below/
60
- end
61
-
62
- specify "should support forwarding" do
63
- app = Rack::Recursive.new(Rack::URLMap.new("/app1" => @app1,
64
- "/app3" => @app3,
65
- "/app4" => @app4))
66
-
67
- res = Rack::MockRequest.new(app).get("/app3")
68
- res.should.be.ok
69
- res.body.should.equal "App1"
70
-
71
- res = Rack::MockRequest.new(app).get("/app4")
72
- res.should.be.ok
73
- res.body.should.equal "App1"
74
- res["X-Path-Info"].should.equal "/quux"
75
- res["X-Query-String"].should.equal "meh"
76
- end
77
- end