rack 1.1.0 → 1.2.0

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 (101) hide show
  1. data/README +23 -26
  2. data/SPEC +3 -3
  3. data/lib/rack/auth/digest/params.rb +1 -1
  4. data/lib/rack/content_length.rb +1 -1
  5. data/lib/rack/etag.rb +15 -6
  6. data/lib/rack/file.rb +3 -1
  7. data/lib/rack/handler/cgi.rb +8 -7
  8. data/lib/rack/handler/fastcgi.rb +1 -1
  9. data/lib/rack/handler/lsws.rb +1 -1
  10. data/lib/rack/handler/mongrel.rb +1 -1
  11. data/lib/rack/handler/scgi.rb +1 -4
  12. data/lib/rack/handler/webrick.rb +10 -6
  13. data/lib/rack/lint.rb +29 -37
  14. data/lib/rack/mime.rb +2 -0
  15. data/lib/rack/mock.rb +2 -1
  16. data/lib/rack/recursive.rb +4 -0
  17. data/lib/rack/request.rb +8 -6
  18. data/lib/rack/response.rb +1 -0
  19. data/lib/rack/rewindable_input.rb +13 -10
  20. data/lib/rack/sendfile.rb +8 -6
  21. data/lib/rack/server.rb +66 -7
  22. data/lib/rack/session/memcache.rb +1 -1
  23. data/lib/rack/urlmap.rb +6 -7
  24. data/lib/rack/utils.rb +64 -22
  25. data/lib/rack.rb +1 -12
  26. data/rack.gemspec +6 -6
  27. data/spec/cgi/lighttpd.conf +25 -0
  28. data/spec/cgi/rackup_stub.rb +6 -0
  29. data/spec/cgi/sample_rackup.ru +5 -0
  30. data/spec/cgi/test +9 -0
  31. data/spec/cgi/test.fcgi +8 -0
  32. data/spec/cgi/test.ru +5 -0
  33. data/spec/multipart/bad_robots +259 -0
  34. data/spec/multipart/binary +0 -0
  35. data/spec/multipart/empty +10 -0
  36. data/spec/multipart/fail_16384_nofile +814 -0
  37. data/spec/multipart/file1.txt +1 -0
  38. data/spec/multipart/filename_and_modification_param +7 -0
  39. data/spec/multipart/filename_with_escaped_quotes +6 -0
  40. data/spec/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
  41. data/spec/multipart/filename_with_percent_escaped_quotes +6 -0
  42. data/spec/multipart/filename_with_unescaped_quotes +6 -0
  43. data/spec/multipart/ie +6 -0
  44. data/spec/multipart/nested +10 -0
  45. data/spec/multipart/none +9 -0
  46. data/spec/multipart/semicolon +6 -0
  47. data/spec/multipart/text +10 -0
  48. data/spec/rackup/config.ru +31 -0
  49. data/{test/spec_rack_auth_basic.rb → spec/spec_auth_basic.rb} +11 -14
  50. data/{test/spec_rack_auth_digest.rb → spec/spec_auth_digest.rb} +18 -21
  51. data/{test/spec_rack_builder.rb → spec/spec_builder.rb} +49 -10
  52. data/{test/spec_rack_cascade.rb → spec/spec_cascade.rb} +7 -10
  53. data/{test/spec_rack_cgi.rb → spec/spec_cgi.rb} +34 -32
  54. data/{test/spec_rack_chunked.rb → spec/spec_chunked.rb} +8 -10
  55. data/{test/spec_rack_commonlogger.rb → spec/spec_commonlogger.rb} +10 -15
  56. data/{test/spec_rack_conditionalget.rb → spec/spec_conditionalget.rb} +5 -7
  57. data/{test/spec_rack_config.rb → spec/spec_config.rb} +6 -7
  58. data/{test/spec_rack_content_length.rb → spec/spec_content_length.rb} +7 -8
  59. data/{test/spec_rack_content_type.rb → spec/spec_content_type.rb} +5 -6
  60. data/{test/spec_rack_deflater.rb → spec/spec_deflater.rb} +11 -13
  61. data/{test/spec_rack_directory.rb → spec/spec_directory.rb} +6 -10
  62. data/{test/spec_rack_etag.rb → spec/spec_etag.rb} +3 -5
  63. data/{test/spec_rack_fastcgi.rb → spec/spec_fastcgi.rb} +36 -29
  64. data/{test/spec_rack_file.rb → spec/spec_file.rb} +9 -13
  65. data/{test/spec_rack_handler.rb → spec/spec_handler.rb} +10 -12
  66. data/{test/spec_rack_head.rb → spec/spec_head.rb} +3 -3
  67. data/{test/spec_rack_lint.rb → spec/spec_lint.rb} +19 -32
  68. data/{test/spec_rack_lobster.rb → spec/spec_lobster.rb} +9 -11
  69. data/{test/spec_rack_lock.rb → spec/spec_lock.rb} +15 -17
  70. data/{test/spec_rack_logger.rb → spec/spec_logger.rb} +6 -7
  71. data/{test/spec_rack_methodoverride.rb → spec/spec_methodoverride.rb} +15 -17
  72. data/{test/spec_rack_mock.rb → spec/spec_mock.rb} +30 -32
  73. data/{test/spec_rack_mongrel.rb → spec/spec_mongrel.rb} +40 -46
  74. data/{test/spec_rack_nulllogger.rb → spec/spec_nulllogger.rb} +4 -5
  75. data/{test/spec_rack_recursive.rb → spec/spec_recursive.rb} +28 -36
  76. data/{test/spec_rack_request.rb → spec/spec_request.rb} +84 -49
  77. data/{test/spec_rack_response.rb → spec/spec_response.rb} +48 -29
  78. data/spec/spec_rewindable_input.rb +118 -0
  79. data/{test/spec_rack_runtime.rb → spec/spec_runtime.rb} +15 -11
  80. data/{test/spec_rack_sendfile.rb → spec/spec_sendfile.rb} +11 -14
  81. data/{test/spec_rack_session_cookie.rb → spec/spec_session_cookie.rb} +15 -18
  82. data/{test/spec_rack_session_memcache.rb → spec/spec_session_memcache.rb} +32 -26
  83. data/{test/spec_rack_session_pool.rb → spec/spec_session_pool.rb} +36 -31
  84. data/spec/spec_showexceptions.rb +23 -0
  85. data/spec/spec_showstatus.rb +79 -0
  86. data/{test/spec_rack_static.rb → spec/spec_static.rb} +5 -9
  87. data/{test/spec_rack_thin.rb → spec/spec_thin.rb} +30 -35
  88. data/{test/spec_rack_urlmap.rb → spec/spec_urlmap.rb} +6 -8
  89. data/{test/spec_rack_utils.rb → spec/spec_utils.rb} +136 -71
  90. data/{test/spec_rack_webrick.rb → spec/spec_webrick.rb} +28 -36
  91. data/spec/testrequest.rb +77 -0
  92. data/spec/unregistered_handler/rack/handler/unregistered.rb +7 -0
  93. data/spec/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  94. metadata +206 -124
  95. data/RDOX +0 -0
  96. data/lib/rack/adapter/camping.rb +0 -22
  97. data/test/spec_rack_camping.rb +0 -51
  98. data/test/spec_rack_rewindable_input.rb +0 -118
  99. data/test/spec_rack_showexceptions.rb +0 -21
  100. data/test/spec_rack_showstatus.rb +0 -72
  101. data/test/spec_rackup.rb +0 -154
data/README CHANGED
@@ -9,16 +9,6 @@ middleware) into a single method call.
9
9
  The exact details of this are described in the Rack specification,
10
10
  which all Rack applications should conform to.
11
11
 
12
- == Specification changes in this release
13
-
14
- With Rack 1.1, the Rack specification (found in SPEC) changed in the
15
- following backward-incompatible ways.
16
-
17
- * Rack::VERSION has been pushed to [1,1].
18
- * rack.logger is now specified.
19
- * The SPEC now allows subclasses of the required types.
20
- * rack.input has to be opened in binary mode.
21
-
22
12
  == Supported web servers
23
13
 
24
14
  The included *handlers* connect all kinds of web servers to Rack:
@@ -46,9 +36,6 @@ changing anything.
46
36
 
47
37
  == Supported web frameworks
48
38
 
49
- The included *adapters* connect Rack with existing Ruby web frameworks:
50
- * Camping
51
-
52
39
  These frameworks include Rack adapters in their distributions:
53
40
  * Camping
54
41
  * Coset
@@ -143,9 +130,9 @@ at my site:
143
130
 
144
131
  == Running the tests
145
132
 
146
- Testing Rack requires the test/spec testing framework:
133
+ Testing Rack requires the bacon testing framework:
147
134
 
148
- gem install test-spec
135
+ gem install bacon
149
136
 
150
137
  There are two rake-based test tasks:
151
138
 
@@ -153,11 +140,10 @@ There are two rake-based test tasks:
153
140
  rake fulltest runs all the tests
154
141
 
155
142
  The fast testsuite has no dependencies outside of the core Ruby
156
- installation and test-spec.
143
+ installation and bacon.
157
144
 
158
145
  To run the test suite completely, you need:
159
146
 
160
- * camping
161
147
  * fcgi
162
148
  * memcache-client
163
149
  * mongrel
@@ -278,7 +264,7 @@ run on port 11211) and memcache-client installed.
278
264
  * Make sure WEBrick respects the :Host option
279
265
  * Many Ruby 1.9 fixes.
280
266
 
281
- * January 3rd, 2009: Ninth public release 1.1.0.
267
+ * January 3rd, 2010: Ninth public release 1.1.0.
282
268
  * Moved Auth::OpenID to rack-contrib.
283
269
  * SPEC change that relaxes Lint slightly to allow subclasses of the
284
270
  required types
@@ -313,17 +299,26 @@ run on port 11211) and memcache-client installed.
313
299
  * Enforce binary encoding in RewindableInput
314
300
  * Set correct external_encoding for handlers that don't use RewindableInput
315
301
 
302
+ * June 13th, 2010: Tenth public release 1.2.0.
303
+ * Removed Camping adapter: Camping 2.0 supports Rack as-is
304
+ * Removed parsing of quoted values
305
+ * Add Request.trace? and Request.options?
306
+ * Add mime-type for .webm and .htc
307
+ * Fix HTTP_X_FORWARDED_FOR
308
+ * Various multipart fixes
309
+ * Switch test suite to bacon
310
+
316
311
  == Contact
317
312
 
318
313
  Please post bugs, suggestions and patches to
319
- the bug tracker at <http://rack.lighthouseapp.com/>.
314
+ the bug tracker at <http://github.com/rack/rack/issues>.
320
315
 
321
316
  Mailing list archives are available at
322
317
  <http://groups.google.com/group/rack-devel>.
323
318
 
324
319
  Git repository (send Git patches to the mailing list):
325
320
  * http://github.com/rack/rack
326
- * http://git.vuxu.org/cgi-bin/gitweb.cgi?p=rack.git
321
+ * http://git.vuxu.org/cgi-bin/gitweb.cgi?p=rack-github.git
327
322
 
328
323
  You are also welcome to join the #rack channel on irc.freenode.net.
329
324
 
@@ -345,12 +340,14 @@ would like to thank:
345
340
  * Tim Fletcher, for the HTTP authentication code.
346
341
  * Luc Heinrich for the Cookie sessions, the static file handler and bugfixes.
347
342
  * Armin Ronacher, for the logo and racktools.
348
- * Aredridel, Ben Alpert, Dan Kubb, Daniel Roethlisberger, Matt Todd,
349
- Tom Robinson, Phil Hagelberg, S. Brent Faulkner, Bosko Milekic,
350
- Daniel Rodríguez Troitiño, Genki Takiuchi, Geoffrey Grosenbach,
351
- Julien Sanchez, Kamal Fariz Mahyuddin, Masayoshi Takahashi, Patrick
352
- Aljordm, Mig, and Kazuhiro Nishiyama for bug fixing and other
353
- improvements.
343
+ * Alex Beregszaszi, Alexander Kahn, Anil Wadghule, Aredridel, Ben
344
+ Alpert, Dan Kubb, Daniel Roethlisberger, Matt Todd, Tom Robinson,
345
+ Phil Hagelberg, S. Brent Faulkner, Bosko Milekic, Daniel Rodríguez
346
+ Troitiño, Genki Takiuchi, Geoffrey Grosenbach, Julien Sanchez, Kamal
347
+ Fariz Mahyuddin, Masayoshi Takahashi, Patrick Aljordm, Mig, Kazuhiro
348
+ Nishiyama, Jon Bardin, Konstantin Haase, Larry Siden, Matias
349
+ Korhonen, Sam Ruby, Simon Chiang, Tim Connor, Timur Batyrshin, and
350
+ Zach Brock for bug fixing and other improvements.
354
351
  * Eric Wong, Hongli Lai, Jeremy Kemper for their continuous support
355
352
  and API improvements.
356
353
  * Yehuda Katz and Carl Lerche for refactoring rackup.
data/SPEC CHANGED
@@ -11,9 +11,9 @@ The *status*,
11
11
  the *headers*,
12
12
  and the *body*.
13
13
  == The Environment
14
- The environment must be an true instance of Hash (no
15
- subclassing allowed) that includes CGI-like headers.
16
- The application is free to modify the environment.
14
+ The environment must be an instance of Hash that includes
15
+ CGI-like headers. The application is free to modify the
16
+ environment.
17
17
  The environment is required to include these variables
18
18
  (adopted from PEP333), except when they'd be empty, but see
19
19
  below.
@@ -35,7 +35,7 @@ module Rack
35
35
  super k.to_s, v.to_s
36
36
  end
37
37
 
38
- UNQUOTED = ['qop', 'nc', 'stale']
38
+ UNQUOTED = ['nc', 'stale']
39
39
 
40
40
  def to_s
41
41
  inject([]) do |parts, (k, v)|
@@ -13,7 +13,7 @@ module Rack
13
13
  status, headers, body = @app.call(env)
14
14
  headers = HeaderHash.new(headers)
15
15
 
16
- if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
16
+ if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
17
17
  !headers['Content-Length'] &&
18
18
  !headers['Transfer-Encoding'] &&
19
19
  (body.respond_to?(:to_ary) || body.respond_to?(:to_str))
data/lib/rack/etag.rb CHANGED
@@ -11,13 +11,22 @@ module Rack
11
11
  status, headers, body = @app.call(env)
12
12
 
13
13
  if !headers.has_key?('ETag')
14
- parts = []
15
- body.each { |part| parts << part.to_s }
16
- headers['ETag'] = %("#{Digest::MD5.hexdigest(parts.join(""))}")
17
- [status, headers, parts]
18
- else
19
- [status, headers, body]
14
+ digest, body = digest_body(body)
15
+ headers['ETag'] = %("#{digest}")
20
16
  end
17
+
18
+ [status, headers, body]
21
19
  end
20
+
21
+ private
22
+ def digest_body(body)
23
+ digest = Digest::MD5.new
24
+ parts = []
25
+ body.each do |part|
26
+ digest << part
27
+ parts << part
28
+ end
29
+ [digest.hexdigest, parts]
30
+ end
22
31
  end
23
32
  end
data/lib/rack/file.rb CHANGED
@@ -3,8 +3,10 @@ require 'rack/utils'
3
3
  require 'rack/mime'
4
4
 
5
5
  module Rack
6
- # Rack::File serves files below the +root+ given, according to the
6
+ # Rack::File serves files below the +root+ directory given, according to the
7
7
  # path info of the Rack request.
8
+ # e.g. when Rack::File.new("/etc") is used, you can access 'passwd' file
9
+ # as http://localhost:9292/passwd
8
10
  #
9
11
  # Handlers can detect if bodies are a Rack::File, and use mechanisms
10
12
  # like sendfile on the +path+.
@@ -4,6 +4,7 @@ module Rack
4
4
  module Handler
5
5
  class CGI
6
6
  def self.run(app, options=nil)
7
+ $stdin.binmode
7
8
  serve app
8
9
  end
9
10
 
@@ -15,7 +16,7 @@ module Rack
15
16
 
16
17
  env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
17
18
 
18
- env.update({"rack.version" => [1,1],
19
+ env.update({"rack.version" => Rack::VERSION,
19
20
  "rack.input" => $stdin,
20
21
  "rack.errors" => $stderr,
21
22
 
@@ -40,20 +41,20 @@ module Rack
40
41
  end
41
42
 
42
43
  def self.send_headers(status, headers)
43
- STDOUT.print "Status: #{status}\r\n"
44
+ $stdout.print "Status: #{status}\r\n"
44
45
  headers.each { |k, vs|
45
46
  vs.split("\n").each { |v|
46
- STDOUT.print "#{k}: #{v}\r\n"
47
+ $stdout.print "#{k}: #{v}\r\n"
47
48
  }
48
49
  }
49
- STDOUT.print "\r\n"
50
- STDOUT.flush
50
+ $stdout.print "\r\n"
51
+ $stdout.flush
51
52
  end
52
53
 
53
54
  def self.send_body(body)
54
55
  body.each { |part|
55
- STDOUT.print part
56
- STDOUT.flush
56
+ $stdout.print part
57
+ $stdout.flush
57
58
  }
58
59
  end
59
60
  end
@@ -36,7 +36,7 @@ module Rack
36
36
 
37
37
  rack_input = RewindableInput.new(request.in)
38
38
 
39
- env.update({"rack.version" => [1,1],
39
+ env.update({"rack.version" => Rack::VERSION,
40
40
  "rack.input" => rack_input,
41
41
  "rack.errors" => request.err,
42
42
 
@@ -20,7 +20,7 @@ module Rack
20
20
  rack_input = RewindableInput.new($stdin.read.to_s)
21
21
 
22
22
  env.update(
23
- "rack.version" => [1,1],
23
+ "rack.version" => Rack::VERSION,
24
24
  "rack.input" => rack_input,
25
25
  "rack.errors" => $stderr,
26
26
  "rack.multithread" => false,
@@ -52,7 +52,7 @@ module Rack
52
52
  rack_input = request.body || StringIO.new('')
53
53
  rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
54
54
 
55
- env.update({"rack.version" => [1,1],
55
+ env.update({"rack.version" => Rack::VERSION,
56
56
  "rack.input" => rack_input,
57
57
  "rack.errors" => $stderr,
58
58
 
@@ -17,9 +17,6 @@ module Rack
17
17
 
18
18
  def initialize(settings = {})
19
19
  @app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
20
- @log = Object.new
21
- def @log.info(*args); end
22
- def @log.error(*args); end
23
20
  super(settings)
24
21
  end
25
22
 
@@ -36,7 +33,7 @@ module Rack
36
33
  rack_input = StringIO.new(input_body)
37
34
  rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
38
35
 
39
- env.update({"rack.version" => [1,1],
36
+ env.update({"rack.version" => Rack::VERSION,
40
37
  "rack.input" => rack_input,
41
38
  "rack.errors" => $stderr,
42
39
  "rack.multithread" => true,
@@ -7,11 +7,15 @@ module Rack
7
7
  class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
8
8
  def self.run(app, options={})
9
9
  options[:BindAddress] = options.delete(:Host) if options[:Host]
10
- server = ::WEBrick::HTTPServer.new(options)
11
- server.mount "/", Rack::Handler::WEBrick, app
12
- trap(:INT) { server.shutdown }
13
- yield server if block_given?
14
- server.start
10
+ @server = ::WEBrick::HTTPServer.new(options)
11
+ @server.mount "/", Rack::Handler::WEBrick, app
12
+ yield @server if block_given?
13
+ @server.start
14
+ end
15
+
16
+ def self.shutdown
17
+ @server.shutdown
18
+ @server = nil
15
19
  end
16
20
 
17
21
  def initialize(server, app)
@@ -26,7 +30,7 @@ module Rack
26
30
  rack_input = StringIO.new(req.body.to_s)
27
31
  rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
28
32
 
29
- env.update({"rack.version" => [1,1],
33
+ env.update({"rack.version" => Rack::VERSION,
30
34
  "rack.input" => rack_input,
31
35
  "rack.errors" => $stderr,
32
36
 
data/lib/rack/lint.rb CHANGED
@@ -7,6 +7,7 @@ module Rack
7
7
  class Lint
8
8
  def initialize(app)
9
9
  @app = app
10
+ @content_length = nil
10
11
  end
11
12
 
12
13
  # :stopdoc:
@@ -51,15 +52,16 @@ module Rack
51
52
  check_headers headers
52
53
  ## and the *body*.
53
54
  check_content_type status, headers
54
- check_content_length status, headers, env
55
+ check_content_length status, headers
56
+ @head_request = env["REQUEST_METHOD"] == "HEAD"
55
57
  [status, headers, self]
56
58
  end
57
59
 
58
60
  ## == The Environment
59
61
  def check_env(env)
60
- ## The environment must be an true instance of Hash (no
61
- ## subclassing allowed) that includes CGI-like headers.
62
- ## The application is free to modify the environment.
62
+ ## The environment must be an instance of Hash that includes
63
+ ## CGI-like headers. The application is free to modify the
64
+ ## environment.
63
65
  assert("env #{env.inspect} is not a Hash, but #{env.class}") {
64
66
  env.kind_of? Hash
65
67
  }
@@ -288,10 +290,6 @@ module Rack
288
290
  @input = input
289
291
  end
290
292
 
291
- def size
292
- @input.size
293
- end
294
-
295
293
  ## * +gets+ must be called without arguments and return a string,
296
294
  ## or +nil+ on EOF.
297
295
  def gets(*args)
@@ -481,7 +479,7 @@ module Rack
481
479
  end
482
480
 
483
481
  ## === The Content-Length
484
- def check_content_length(status, headers, env)
482
+ def check_content_length(status, headers)
485
483
  headers.each { |key, value|
486
484
  if key.downcase == 'content-length'
487
485
  ## There must not be a <tt>Content-Length</tt> header when the
@@ -489,49 +487,43 @@ module Rack
489
487
  assert("Content-Length header found in #{status} response, not allowed") {
490
488
  not Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
491
489
  }
492
-
493
- bytes = 0
494
- string_body = true
495
-
496
- if @body.respond_to?(:to_ary)
497
- @body.each { |part|
498
- unless part.kind_of?(String)
499
- string_body = false
500
- break
501
- end
502
-
503
- bytes += Rack::Utils.bytesize(part)
504
- }
505
-
506
- if env["REQUEST_METHOD"] == "HEAD"
507
- assert("Response body was given for HEAD request, but should be empty") {
508
- bytes == 0
509
- }
510
- else
511
- if string_body
512
- assert("Content-Length header was #{value}, but should be #{bytes}") {
513
- value == bytes.to_s
514
- }
515
- end
516
- end
517
- end
518
-
519
- return
490
+ @content_length = value
520
491
  end
521
492
  }
522
493
  end
523
494
 
495
+ def verify_content_length(bytes)
496
+ if @head_request
497
+ assert("Response body was given for HEAD request, but should be empty") {
498
+ bytes == 0
499
+ }
500
+ elsif @content_length
501
+ assert("Content-Length header was #{@content_length}, but should be #{bytes}") {
502
+ @content_length == bytes.to_s
503
+ }
504
+ end
505
+ end
506
+
524
507
  ## === The Body
525
508
  def each
526
509
  @closed = false
510
+ bytes = 0
511
+
527
512
  ## The Body must respond to +each+
513
+ assert("Response body must respond to each") do
514
+ @body.respond_to?(:each)
515
+ end
516
+
528
517
  @body.each { |part|
529
518
  ## and must only yield String values.
530
519
  assert("Body yielded non-string value #{part.inspect}") {
531
520
  part.kind_of? String
532
521
  }
522
+ bytes += Rack::Utils.bytesize(part)
533
523
  yield part
534
524
  }
525
+ verify_content_length(bytes)
526
+
535
527
  ##
536
528
  ## The Body itself should not be an instance of String, as this will
537
529
  ## break in Ruby 1.9.
data/lib/rack/mime.rb CHANGED
@@ -87,6 +87,7 @@ module Rack
87
87
  ".gif" => "image/gif",
88
88
  ".gz" => "application/x-gzip",
89
89
  ".h" => "text/x-c",
90
+ ".htc" => "text/x-component",
90
91
  ".hh" => "text/x-c",
91
92
  ".htm" => "text/html",
92
93
  ".html" => "text/html",
@@ -186,6 +187,7 @@ module Rack
186
187
  ".vrml" => "model/vrml",
187
188
  ".war" => "application/java-archive",
188
189
  ".wav" => "audio/x-wav",
190
+ ".webm" => "video/webm",
189
191
  ".wma" => "audio/x-ms-wma",
190
192
  ".wmv" => "video/x-ms-wmv",
191
193
  ".wmx" => "video/x-ms-wmx",
data/lib/rack/mock.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'uri'
2
2
  require 'stringio'
3
+ require 'rack'
3
4
  require 'rack/lint'
4
5
  require 'rack/utils'
5
6
  require 'rack/response'
@@ -40,7 +41,7 @@ module Rack
40
41
  end
41
42
 
42
43
  DEFAULT_ENV = {
43
- "rack.version" => [1,1],
44
+ "rack.version" => Rack::VERSION,
44
45
  "rack.input" => StringIO.new,
45
46
  "rack.errors" => StringIO.new,
46
47
  "rack.multithread" => true,
@@ -35,6 +35,10 @@ module Rack
35
35
  end
36
36
 
37
37
  def call(env)
38
+ dup._call(env)
39
+ end
40
+
41
+ def _call(env)
38
42
  @script_name = env["SCRIPT_NAME"]
39
43
  @app.call(env.merge('rack.recursive.include' => method(:include)))
40
44
  rescue ForwardRequest => req
data/lib/rack/request.rb CHANGED
@@ -80,11 +80,13 @@ module Rack
80
80
  def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
81
81
  def path_info=(s); @env["PATH_INFO"] = s.to_s end
82
82
 
83
- def get?; request_method == "GET" end
84
- def post?; request_method == "POST" end
85
- def put?; request_method == "PUT" end
86
- def delete?; request_method == "DELETE" end
87
- def head?; request_method == "HEAD" end
83
+ def delete?; request_method == "DELETE" end
84
+ def get?; request_method == "GET" end
85
+ def head?; request_method == "HEAD" end
86
+ def options?; request_method == "OPTIONS" end
87
+ def post?; request_method == "POST" end
88
+ def put?; request_method == "PUT" end
89
+ def trace?; request_method == "TRACE" end
88
90
 
89
91
  # The set of form-data media-types. Requests that do not indicate
90
92
  # one of the media types presents in this list will not be eligible
@@ -253,7 +255,7 @@ module Rack
253
255
 
254
256
  def ip
255
257
  if addr = @env['HTTP_X_FORWARDED_FOR']
256
- addr.split(',').last.strip
258
+ (addr.split(',').grep(/\d\./).first || @env['REMOTE_ADDR']).to_s.strip
257
259
  else
258
260
  @env['REMOTE_ADDR']
259
261
  end
data/lib/rack/response.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rack/request'
2
2
  require 'rack/utils'
3
+ require 'time'
3
4
 
4
5
  module Rack
5
6
  # Rack::Response provides a convenient interface to create a Rack
@@ -1,4 +1,6 @@
1
+ # -*- encoding: binary -*-
1
2
  require 'tempfile'
3
+ require 'rack/utils'
2
4
 
3
5
  module Rack
4
6
  # Class which can make any IO object rewindable, including non-rewindable ones. It does
@@ -16,27 +18,27 @@ module Rack
16
18
  @rewindable_io = nil
17
19
  @unlinked = false
18
20
  end
19
-
21
+
20
22
  def gets
21
23
  make_rewindable unless @rewindable_io
22
24
  @rewindable_io.gets
23
25
  end
24
-
26
+
25
27
  def read(*args)
26
28
  make_rewindable unless @rewindable_io
27
29
  @rewindable_io.read(*args)
28
30
  end
29
-
31
+
30
32
  def each(&block)
31
33
  make_rewindable unless @rewindable_io
32
34
  @rewindable_io.each(&block)
33
35
  end
34
-
36
+
35
37
  def rewind
36
38
  make_rewindable unless @rewindable_io
37
39
  @rewindable_io.rewind
38
40
  end
39
-
41
+
40
42
  # Closes this RewindableInput object without closing the originally
41
43
  # wrapped IO oject. Cleans up any temporary resources that this RewindableInput
42
44
  # has created.
@@ -52,9 +54,9 @@ module Rack
52
54
  @rewindable_io = nil
53
55
  end
54
56
  end
55
-
57
+
56
58
  private
57
-
59
+
58
60
  # Ruby's Tempfile class has a bug. Subclass it and fix it.
59
61
  class Tempfile < ::Tempfile
60
62
  def _close
@@ -76,15 +78,16 @@ module Rack
76
78
  @rewindable_io.binmode
77
79
  if filesystem_has_posix_semantics?
78
80
  @rewindable_io.unlink
81
+ raise 'Unlink failed. IO closed.' if @rewindable_io.closed?
79
82
  @unlinked = true
80
83
  end
81
-
84
+
82
85
  buffer = ""
83
86
  while @io.read(1024 * 4, buffer)
84
87
  entire_buffer_written_out = false
85
88
  while !entire_buffer_written_out
86
89
  written = @rewindable_io.write(buffer)
87
- entire_buffer_written_out = written == buffer.size
90
+ entire_buffer_written_out = written == Rack::Utils.bytesize(buffer)
88
91
  if !entire_buffer_written_out
89
92
  buffer.slice!(0 .. written - 1)
90
93
  end
@@ -92,7 +95,7 @@ module Rack
92
95
  end
93
96
  @rewindable_io.rewind
94
97
  end
95
-
98
+
96
99
  def filesystem_has_posix_semantics?
97
100
  RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/
98
101
  end
data/lib/rack/sendfile.rb CHANGED
@@ -2,7 +2,9 @@ require 'rack/file'
2
2
 
3
3
  module Rack
4
4
  class File #:nodoc:
5
- alias :to_path :path
5
+ unless instance_methods(false).include?('to_path')
6
+ alias :to_path :path
7
+ end
6
8
  end
7
9
 
8
10
  # = Sendfile
@@ -11,7 +13,7 @@ module Rack
11
13
  # served from a file and replaces it with a server specific X-Sendfile
12
14
  # header. The web server is then responsible for writing the file contents
13
15
  # to the client. This can dramatically reduce the amount of work required
14
- # by the Ruby backend and takes advantage of the web servers optimized file
16
+ # by the Ruby backend and takes advantage of the web server's optimized file
15
17
  # delivery code.
16
18
  #
17
19
  # In order to take advantage of this middleware, the response body must
@@ -31,19 +33,19 @@ module Rack
31
33
  # a private "/files/" area, enable X-Accel-Redirect, and pass the special
32
34
  # X-Sendfile-Type and X-Accel-Mapping headers to the backend:
33
35
  #
34
- # location /files/ {
36
+ # location ~ /files/(.*) {
35
37
  # internal;
36
- # alias /var/www/;
38
+ # alias /var/www/$1;
37
39
  # }
38
40
  #
39
41
  # location / {
40
- # proxy_redirect false;
42
+ # proxy_redirect off;
41
43
  #
42
44
  # proxy_set_header Host $host;
43
45
  # proxy_set_header X-Real-IP $remote_addr;
44
46
  # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
45
47
  #
46
- # proxy_set_header X-Sendfile-Type X-Accel-Redirect
48
+ # proxy_set_header X-Sendfile-Type X-Accel-Redirect;
47
49
  # proxy_set_header X-Accel-Mapping /files/=/var/www/;
48
50
  #
49
51
  # proxy_pass http://127.0.0.1:8080/;