rack 2.0.3 → 2.2.4

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 (190) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +708 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +152 -150
  6. data/Rakefile +37 -23
  7. data/{SPEC → SPEC.rdoc} +35 -10
  8. data/bin/rackup +1 -0
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +3 -1
  11. data/example/protectedlobster.ru +2 -0
  12. data/lib/rack/auth/abstract/handler.rb +3 -1
  13. data/lib/rack/auth/abstract/request.rb +1 -1
  14. data/lib/rack/auth/basic.rb +7 -4
  15. data/lib/rack/auth/digest/md5.rb +13 -11
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +4 -2
  18. data/lib/rack/auth/digest/request.rb +5 -3
  19. data/lib/rack/body_proxy.rb +15 -14
  20. data/lib/rack/builder.rb +116 -23
  21. data/lib/rack/cascade.rb +28 -12
  22. data/lib/rack/chunked.rb +68 -20
  23. data/lib/rack/common_logger.rb +36 -25
  24. data/lib/rack/conditional_get.rb +20 -16
  25. data/lib/rack/config.rb +2 -0
  26. data/lib/rack/content_length.rb +8 -7
  27. data/lib/rack/content_type.rb +5 -4
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +59 -34
  30. data/lib/rack/directory.rb +84 -64
  31. data/lib/rack/etag.rb +8 -5
  32. data/lib/rack/events.rb +19 -20
  33. data/lib/rack/file.rb +4 -173
  34. data/lib/rack/files.rb +218 -0
  35. data/lib/rack/handler/cgi.rb +2 -3
  36. data/lib/rack/handler/fastcgi.rb +4 -4
  37. data/lib/rack/handler/lsws.rb +3 -3
  38. data/lib/rack/handler/scgi.rb +9 -8
  39. data/lib/rack/handler/thin.rb +3 -3
  40. data/lib/rack/handler/webrick.rb +15 -6
  41. data/lib/rack/handler.rb +7 -2
  42. data/lib/rack/head.rb +1 -1
  43. data/lib/rack/lint.rb +72 -26
  44. data/lib/rack/lobster.rb +10 -10
  45. data/lib/rack/lock.rb +14 -4
  46. data/lib/rack/logger.rb +2 -0
  47. data/lib/rack/media_type.rb +10 -5
  48. data/lib/rack/method_override.rb +9 -3
  49. data/lib/rack/mime.rb +9 -1
  50. data/lib/rack/mock.rb +98 -21
  51. data/lib/rack/multipart/generator.rb +17 -13
  52. data/lib/rack/multipart/parser.rb +61 -63
  53. data/lib/rack/multipart/uploaded_file.rb +15 -7
  54. data/lib/rack/multipart.rb +5 -4
  55. data/lib/rack/null_logger.rb +2 -0
  56. data/lib/rack/query_parser.rb +59 -30
  57. data/lib/rack/recursive.rb +7 -5
  58. data/lib/rack/reloader.rb +8 -4
  59. data/lib/rack/request.rb +228 -56
  60. data/lib/rack/response.rb +127 -44
  61. data/lib/rack/rewindable_input.rb +4 -3
  62. data/lib/rack/runtime.rb +6 -4
  63. data/lib/rack/sendfile.rb +13 -9
  64. data/lib/rack/server.rb +95 -24
  65. data/lib/rack/session/abstract/id.rb +100 -22
  66. data/lib/rack/session/cookie.rb +22 -14
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +18 -9
  69. data/lib/rack/show_exceptions.rb +22 -18
  70. data/lib/rack/show_status.rb +9 -9
  71. data/lib/rack/static.rb +23 -11
  72. data/lib/rack/tempfile_reaper.rb +1 -1
  73. data/lib/rack/urlmap.rb +12 -6
  74. data/lib/rack/utils.rb +107 -111
  75. data/lib/rack/version.rb +29 -0
  76. data/lib/rack.rb +67 -73
  77. data/rack.gemspec +40 -29
  78. metadata +25 -181
  79. data/HISTORY.md +0 -505
  80. data/test/builder/an_underscore_app.rb +0 -5
  81. data/test/builder/anything.rb +0 -5
  82. data/test/builder/comment.ru +0 -4
  83. data/test/builder/end.ru +0 -5
  84. data/test/builder/line.ru +0 -1
  85. data/test/builder/options.ru +0 -2
  86. data/test/cgi/assets/folder/test.js +0 -1
  87. data/test/cgi/assets/fonts/font.eot +0 -1
  88. data/test/cgi/assets/images/image.png +0 -1
  89. data/test/cgi/assets/index.html +0 -1
  90. data/test/cgi/assets/javascripts/app.js +0 -1
  91. data/test/cgi/assets/stylesheets/app.css +0 -1
  92. data/test/cgi/lighttpd.conf +0 -26
  93. data/test/cgi/rackup_stub.rb +0 -6
  94. data/test/cgi/sample_rackup.ru +0 -5
  95. data/test/cgi/test +0 -9
  96. data/test/cgi/test+directory/test+file +0 -1
  97. data/test/cgi/test.fcgi +0 -9
  98. data/test/cgi/test.gz +0 -0
  99. data/test/cgi/test.ru +0 -5
  100. data/test/gemloader.rb +0 -10
  101. data/test/helper.rb +0 -34
  102. data/test/multipart/bad_robots +0 -259
  103. data/test/multipart/binary +0 -0
  104. data/test/multipart/content_type_and_no_filename +0 -6
  105. data/test/multipart/empty +0 -10
  106. data/test/multipart/fail_16384_nofile +0 -814
  107. data/test/multipart/file1.txt +0 -1
  108. data/test/multipart/filename_and_modification_param +0 -7
  109. data/test/multipart/filename_and_no_name +0 -6
  110. data/test/multipart/filename_with_encoded_words +0 -7
  111. data/test/multipart/filename_with_escaped_quotes +0 -6
  112. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  113. data/test/multipart/filename_with_null_byte +0 -7
  114. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  115. data/test/multipart/filename_with_single_quote +0 -7
  116. data/test/multipart/filename_with_unescaped_percentages +0 -6
  117. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  119. data/test/multipart/filename_with_unescaped_quotes +0 -6
  120. data/test/multipart/ie +0 -6
  121. data/test/multipart/invalid_character +0 -6
  122. data/test/multipart/mixed_files +0 -21
  123. data/test/multipart/nested +0 -10
  124. data/test/multipart/none +0 -9
  125. data/test/multipart/quoted +0 -15
  126. data/test/multipart/rack-logo.png +0 -0
  127. data/test/multipart/semicolon +0 -6
  128. data/test/multipart/text +0 -15
  129. data/test/multipart/three_files_three_fields +0 -31
  130. data/test/multipart/unity3d_wwwform +0 -11
  131. data/test/multipart/webkit +0 -32
  132. data/test/rackup/config.ru +0 -31
  133. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  134. data/test/spec_auth_basic.rb +0 -89
  135. data/test/spec_auth_digest.rb +0 -260
  136. data/test/spec_body_proxy.rb +0 -85
  137. data/test/spec_builder.rb +0 -233
  138. data/test/spec_cascade.rb +0 -63
  139. data/test/spec_cgi.rb +0 -84
  140. data/test/spec_chunked.rb +0 -103
  141. data/test/spec_common_logger.rb +0 -95
  142. data/test/spec_conditional_get.rb +0 -103
  143. data/test/spec_config.rb +0 -23
  144. data/test/spec_content_length.rb +0 -86
  145. data/test/spec_content_type.rb +0 -46
  146. data/test/spec_deflater.rb +0 -375
  147. data/test/spec_directory.rb +0 -148
  148. data/test/spec_etag.rb +0 -108
  149. data/test/spec_events.rb +0 -133
  150. data/test/spec_fastcgi.rb +0 -85
  151. data/test/spec_file.rb +0 -264
  152. data/test/spec_handler.rb +0 -57
  153. data/test/spec_head.rb +0 -46
  154. data/test/spec_lint.rb +0 -515
  155. data/test/spec_lobster.rb +0 -59
  156. data/test/spec_lock.rb +0 -194
  157. data/test/spec_logger.rb +0 -24
  158. data/test/spec_media_type.rb +0 -42
  159. data/test/spec_method_override.rb +0 -96
  160. data/test/spec_mime.rb +0 -51
  161. data/test/spec_mock.rb +0 -359
  162. data/test/spec_multipart.rb +0 -722
  163. data/test/spec_null_logger.rb +0 -21
  164. data/test/spec_recursive.rb +0 -75
  165. data/test/spec_request.rb +0 -1393
  166. data/test/spec_response.rb +0 -510
  167. data/test/spec_rewindable_input.rb +0 -128
  168. data/test/spec_runtime.rb +0 -50
  169. data/test/spec_sendfile.rb +0 -125
  170. data/test/spec_server.rb +0 -193
  171. data/test/spec_session_abstract_id.rb +0 -31
  172. data/test/spec_session_abstract_session_hash.rb +0 -45
  173. data/test/spec_session_cookie.rb +0 -442
  174. data/test/spec_session_memcache.rb +0 -320
  175. data/test/spec_session_pool.rb +0 -210
  176. data/test/spec_show_exceptions.rb +0 -80
  177. data/test/spec_show_status.rb +0 -104
  178. data/test/spec_static.rb +0 -184
  179. data/test/spec_tempfile_reaper.rb +0 -64
  180. data/test/spec_thin.rb +0 -96
  181. data/test/spec_urlmap.rb +0 -237
  182. data/test/spec_utils.rb +0 -742
  183. data/test/spec_version.rb +0 -11
  184. data/test/spec_webrick.rb +0 -209
  185. data/test/static/another/index.html +0 -1
  186. data/test/static/foo.html +0 -1
  187. data/test/static/index.html +0 -1
  188. data/test/testrequest.rb +0 -78
  189. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  190. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/test/spec_version.rb DELETED
@@ -1,11 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require 'minitest/autorun'
3
- require 'rack'
4
-
5
- describe Rack do
6
- describe 'version' do
7
- it 'defaults to a hard-coded api version' do
8
- Rack.version.must_equal "1.3"
9
- end
10
- end
11
- end
data/test/spec_webrick.rb DELETED
@@ -1,209 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack/mock'
3
- require 'concurrent/utility/native_integer'
4
- require 'concurrent/atomic/count_down_latch'
5
- require File.expand_path('../testrequest', __FILE__)
6
-
7
- Thread.abort_on_exception = true
8
-
9
- describe Rack::Handler::WEBrick do
10
- include TestRequest::Helpers
11
-
12
- before do
13
- @server = WEBrick::HTTPServer.new(:Host => @host='127.0.0.1',
14
- :Port => @port=9202,
15
- :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
16
- :AccessLog => [])
17
- @server.mount "/test", Rack::Handler::WEBrick,
18
- Rack::Lint.new(TestRequest.new)
19
- @thread = Thread.new { @server.start }
20
- trap(:INT) { @server.shutdown }
21
- @status_thread = Thread.new do
22
- seconds = 10
23
- wait_time = 0.1
24
- until is_running? || seconds <= 0
25
- seconds -= wait_time
26
- sleep wait_time
27
- end
28
- raise "Server never reached status 'Running'" unless is_running?
29
- end
30
- end
31
-
32
- def is_running?
33
- @server.status == :Running
34
- end
35
-
36
- it "respond" do
37
- GET("/test")
38
- status.must_equal 200
39
- end
40
-
41
- it "be a WEBrick" do
42
- GET("/test")
43
- status.must_equal 200
44
- response["SERVER_SOFTWARE"].must_match(/WEBrick/)
45
- response["HTTP_VERSION"].must_equal "HTTP/1.1"
46
- response["SERVER_PROTOCOL"].must_equal "HTTP/1.1"
47
- response["SERVER_PORT"].must_equal "9202"
48
- response["SERVER_NAME"].must_equal "127.0.0.1"
49
- end
50
-
51
- it "have rack headers" do
52
- GET("/test")
53
- response["rack.version"].must_equal [1,3]
54
- response["rack.multithread"].must_equal true
55
- assert_equal false, response["rack.multiprocess"]
56
- assert_equal false, response["rack.run_once"]
57
- end
58
-
59
- it "have CGI headers on GET" do
60
- GET("/test")
61
- response["REQUEST_METHOD"].must_equal "GET"
62
- response["SCRIPT_NAME"].must_equal "/test"
63
- response["REQUEST_PATH"].must_equal "/test"
64
- response["PATH_INFO"].must_equal ""
65
- response["QUERY_STRING"].must_equal ""
66
- response["test.postdata"].must_equal ""
67
-
68
- GET("/test/foo?quux=1")
69
- response["REQUEST_METHOD"].must_equal "GET"
70
- response["SCRIPT_NAME"].must_equal "/test"
71
- response["REQUEST_PATH"].must_equal "/test/foo"
72
- response["PATH_INFO"].must_equal "/foo"
73
- response["QUERY_STRING"].must_equal "quux=1"
74
-
75
- GET("/test/foo%25encoding?quux=1")
76
- response["REQUEST_METHOD"].must_equal "GET"
77
- response["SCRIPT_NAME"].must_equal "/test"
78
- response["REQUEST_PATH"].must_equal "/test/foo%25encoding"
79
- response["PATH_INFO"].must_equal "/foo%25encoding"
80
- response["QUERY_STRING"].must_equal "quux=1"
81
- end
82
-
83
- it "have CGI headers on POST" do
84
- POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
85
- status.must_equal 200
86
- response["REQUEST_METHOD"].must_equal "POST"
87
- response["SCRIPT_NAME"].must_equal "/test"
88
- response["REQUEST_PATH"].must_equal "/test"
89
- response["PATH_INFO"].must_equal ""
90
- response["QUERY_STRING"].must_equal ""
91
- response["HTTP_X_TEST_HEADER"].must_equal "42"
92
- response["test.postdata"].must_equal "rack-form-data=23"
93
- end
94
-
95
- it "support HTTP auth" do
96
- GET("/test", {:user => "ruth", :passwd => "secret"})
97
- response["HTTP_AUTHORIZATION"].must_equal "Basic cnV0aDpzZWNyZXQ="
98
- end
99
-
100
- it "set status" do
101
- GET("/test?secret")
102
- status.must_equal 403
103
- response["rack.url_scheme"].must_equal "http"
104
- end
105
-
106
- it "correctly set cookies" do
107
- @server.mount "/cookie-test", Rack::Handler::WEBrick,
108
- Rack::Lint.new(lambda { |req|
109
- res = Rack::Response.new
110
- res.set_cookie "one", "1"
111
- res.set_cookie "two", "2"
112
- res.finish
113
- })
114
-
115
- Net::HTTP.start(@host, @port) { |http|
116
- res = http.get("/cookie-test")
117
- res.code.to_i.must_equal 200
118
- res.get_fields("set-cookie").must_equal ["one=1", "two=2"]
119
- }
120
- end
121
-
122
- it "provide a .run" do
123
- block_ran = false
124
- latch = Concurrent::CountDownLatch.new 1
125
-
126
- t = Thread.new do
127
- Rack::Handler::WEBrick.run(lambda {},
128
- {
129
- :Host => '127.0.0.1',
130
- :Port => 9210,
131
- :Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
132
- :AccessLog => []}) { |server|
133
- block_ran = true
134
- assert_kind_of WEBrick::HTTPServer, server
135
- @s = server
136
- latch.count_down
137
- }
138
- end
139
-
140
- latch.wait
141
- @s.shutdown
142
- t.join
143
- end
144
-
145
- it "return repeated headers" do
146
- @server.mount "/headers", Rack::Handler::WEBrick,
147
- Rack::Lint.new(lambda { |req|
148
- [
149
- 401,
150
- { "Content-Type" => "text/plain",
151
- "WWW-Authenticate" => "Bar realm=X\nBaz realm=Y" },
152
- [""]
153
- ]
154
- })
155
-
156
- Net::HTTP.start(@host, @port) { |http|
157
- res = http.get("/headers")
158
- res.code.to_i.must_equal 401
159
- res["www-authenticate"].must_equal "Bar realm=X, Baz realm=Y"
160
- }
161
- end
162
-
163
- it "support Rack partial hijack" do
164
- io_lambda = lambda{ |io|
165
- 5.times do
166
- io.write "David\r\n"
167
- end
168
- io.close
169
- }
170
-
171
- @server.mount "/partial", Rack::Handler::WEBrick,
172
- Rack::Lint.new(lambda{ |req|
173
- [
174
- 200,
175
- [ [ "rack.hijack", io_lambda ] ],
176
- [""]
177
- ]
178
- })
179
-
180
- Net::HTTP.start(@host, @port){ |http|
181
- res = http.get("/partial")
182
- res.body.must_equal "David\r\nDavid\r\nDavid\r\nDavid\r\nDavid\r\n"
183
- }
184
- end
185
-
186
- it "produce correct HTTP semantics with and without app chunking" do
187
- @server.mount "/chunked", Rack::Handler::WEBrick,
188
- Rack::Lint.new(lambda{ |req|
189
- [
190
- 200,
191
- {"Transfer-Encoding" => "chunked"},
192
- ["7\r\nchunked\r\n0\r\n\r\n"]
193
- ]
194
- })
195
-
196
- Net::HTTP.start(@host, @port){ |http|
197
- res = http.get("/chunked")
198
- res["Transfer-Encoding"].must_equal "chunked"
199
- res["Content-Length"].must_be_nil
200
- res.body.must_equal "chunked"
201
- }
202
- end
203
-
204
- after do
205
- @status_thread.join
206
- @server.shutdown
207
- @thread.join
208
- end
209
- end
@@ -1 +0,0 @@
1
- another index!
data/test/static/foo.html DELETED
@@ -1 +0,0 @@
1
- foo.html!
@@ -1 +0,0 @@
1
- index!
data/test/testrequest.rb DELETED
@@ -1,78 +0,0 @@
1
- require 'yaml'
2
- require 'net/http'
3
- require 'rack/lint'
4
-
5
- class TestRequest
6
- NOSERIALIZE = [Method, Proc, Rack::Lint::InputWrapper]
7
-
8
- def call(env)
9
- status = env["QUERY_STRING"] =~ /secret/ ? 403 : 200
10
- env["test.postdata"] = env["rack.input"].read
11
- minienv = env.dup
12
- # This may in the future want to replace with a dummy value instead.
13
- minienv.delete_if { |k,v| NOSERIALIZE.any? { |c| v.kind_of?(c) } }
14
- body = minienv.to_yaml
15
- size = body.bytesize
16
- [status, {"Content-Type" => "text/yaml", "Content-Length" => size.to_s}, [body]]
17
- end
18
-
19
- module Helpers
20
- attr_reader :status, :response
21
-
22
- ROOT = File.expand_path(File.dirname(__FILE__) + "/..")
23
- ENV["RUBYOPT"] = "-I#{ROOT}/lib -rubygems"
24
-
25
- def root
26
- ROOT
27
- end
28
-
29
- def rackup
30
- "#{ROOT}/bin/rackup"
31
- end
32
-
33
- def GET(path, header={})
34
- Net::HTTP.start(@host, @port) { |http|
35
- user = header.delete(:user)
36
- passwd = header.delete(:passwd)
37
-
38
- get = Net::HTTP::Get.new(path, header)
39
- get.basic_auth user, passwd if user && passwd
40
- http.request(get) { |response|
41
- @status = response.code.to_i
42
- begin
43
- @response = YAML.load(response.body)
44
- rescue TypeError, ArgumentError
45
- @response = nil
46
- end
47
- }
48
- }
49
- end
50
-
51
- def POST(path, formdata={}, header={})
52
- Net::HTTP.start(@host, @port) { |http|
53
- user = header.delete(:user)
54
- passwd = header.delete(:passwd)
55
-
56
- post = Net::HTTP::Post.new(path, header)
57
- post.form_data = formdata
58
- post.basic_auth user, passwd if user && passwd
59
- http.request(post) { |response|
60
- @status = response.code.to_i
61
- @response = YAML.load(response.body)
62
- }
63
- }
64
- end
65
- end
66
- end
67
-
68
- class StreamingRequest
69
- def self.call(env)
70
- [200, {"Content-Type" => "text/plain"}, new]
71
- end
72
-
73
- def each
74
- yield "hello there!\n"
75
- sleep 5
76
- yield "that is all.\n"
77
- end
78
- end
@@ -1,7 +0,0 @@
1
- module Rack
2
- module Handler
3
- # this class doesn't do anything, we're just seeing if we get it.
4
- class Unregistered
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Rack
2
- module Handler
3
- # this class doesn't do anything, we're just seeing if we get it.
4
- class UnregisteredLongOne
5
- end
6
- end
7
- end