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