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,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Rack::Cascade tries a request on several apps, and returns the
3
5
  # first response that is not 404 or 405 (or in a list of configurable
4
6
  # status codes).
5
7
 
6
8
  class Cascade
7
- NotFound = [404, {CONTENT_TYPE => "text/plain"}, []]
9
+ NotFound = [404, { CONTENT_TYPE => "text/plain" }, []]
8
10
 
9
11
  attr_reader :apps
10
12
 
11
- def initialize(apps, catch=[404, 405])
12
- @apps = []; @has_app = {}
13
+ def initialize(apps, catch = [404, 405])
14
+ @apps = []
13
15
  apps.each { |app| add app }
14
16
 
15
17
  @catch = {}
@@ -39,12 +41,11 @@ module Rack
39
41
  end
40
42
 
41
43
  def add(app)
42
- @has_app[app] = true
43
44
  @apps << app
44
45
  end
45
46
 
46
47
  def include?(app)
47
- @has_app.include? app
48
+ @apps.include?(app)
48
49
  end
49
50
 
50
51
  alias_method :<<, :add
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/utils'
2
4
 
3
5
  module Rack
@@ -10,7 +12,7 @@ module Rack
10
12
  # A body wrapper that emits chunked responses
11
13
  class Body
12
14
  TERM = "\r\n"
13
- TAIL = "0#{TERM}#{TERM}"
15
+ TAIL = "0#{TERM}"
14
16
 
15
17
  include Rack::Utils
16
18
 
@@ -18,7 +20,7 @@ module Rack
18
20
  @body = body
19
21
  end
20
22
 
21
- def each
23
+ def each(&block)
22
24
  term = TERM
23
25
  @body.each do |chunk|
24
26
  size = chunk.bytesize
@@ -28,11 +30,28 @@ module Rack
28
30
  yield [size.to_s(16), term, chunk, term].join
29
31
  end
30
32
  yield TAIL
33
+ insert_trailers(&block)
34
+ yield TERM
31
35
  end
32
36
 
33
37
  def close
34
38
  @body.close if @body.respond_to?(:close)
35
39
  end
40
+
41
+ private
42
+
43
+ def insert_trailers(&block)
44
+ end
45
+ end
46
+
47
+ class TrailerBody < Body
48
+ private
49
+
50
+ def insert_trailers(&block)
51
+ @body.trailers.each_pair do |k, v|
52
+ yield "#{k}: #{v}\r\n"
53
+ end
54
+ end
36
55
  end
37
56
 
38
57
  def initialize(app)
@@ -43,7 +62,7 @@ module Rack
43
62
  # a version (nor response headers)
44
63
  def chunkable_version?(ver)
45
64
  case ver
46
- when "HTTP/1.0", nil, "HTTP/0.9"
65
+ when 'HTTP/1.0', nil, 'HTTP/0.9'
47
66
  false
48
67
  else
49
68
  true
@@ -54,15 +73,19 @@ module Rack
54
73
  status, headers, body = @app.call(env)
55
74
  headers = HeaderHash.new(headers)
56
75
 
57
- if ! chunkable_version?(env[HTTP_VERSION]) ||
58
- STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
76
+ if ! chunkable_version?(env[SERVER_PROTOCOL]) ||
77
+ STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) ||
59
78
  headers[CONTENT_LENGTH] ||
60
79
  headers[TRANSFER_ENCODING]
61
80
  [status, headers, body]
62
81
  else
63
82
  headers.delete(CONTENT_LENGTH)
64
83
  headers[TRANSFER_ENCODING] = 'chunked'
65
- [status, headers, Body.new(body)]
84
+ if headers['Trailer']
85
+ [status, headers, TrailerBody.new(body)]
86
+ else
87
+ [status, headers, Body.new(body)]
88
+ end
66
89
  end
67
90
  end
68
91
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/body_proxy'
2
4
 
3
5
  module Rack
@@ -23,13 +25,13 @@ module Rack
23
25
  # %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
24
26
  FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
25
27
 
26
- def initialize(app, logger=nil)
28
+ def initialize(app, logger = nil)
27
29
  @app = app
28
30
  @logger = logger
29
31
  end
30
32
 
31
33
  def call(env)
32
- began_at = Time.now
34
+ began_at = Utils.clock_time
33
35
  status, header, body = @app.call(env)
34
36
  header = Utils::HeaderHash.new(header)
35
37
  body = BodyProxy.new(body) { log(env, status, header, began_at) }
@@ -39,20 +41,19 @@ module Rack
39
41
  private
40
42
 
41
43
  def log(env, status, header, began_at)
42
- now = Time.now
43
44
  length = extract_content_length(header)
44
45
 
45
46
  msg = FORMAT % [
46
47
  env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
47
48
  env["REMOTE_USER"] || "-",
48
- now.strftime("%d/%b/%Y:%H:%M:%S %z"),
49
+ Time.now.strftime("%d/%b/%Y:%H:%M:%S %z"),
49
50
  env[REQUEST_METHOD],
50
51
  env[PATH_INFO],
51
52
  env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
52
- env[HTTP_VERSION],
53
+ env[SERVER_PROTOCOL],
53
54
  status.to_s[0..3],
54
55
  length,
55
- now - began_at ]
56
+ Utils.clock_time - began_at ]
56
57
 
57
58
  logger = @logger || env[RACK_ERRORS]
58
59
  # Standard library logger doesn't support write but it supports << which actually
@@ -65,8 +66,8 @@ module Rack
65
66
  end
66
67
 
67
68
  def extract_content_length(headers)
68
- value = headers[CONTENT_LENGTH] or return '-'
69
- value.to_s == '0' ? '-' : value
69
+ value = headers[CONTENT_LENGTH]
70
+ !value || value.to_s == '0' ? '-' : value
70
71
  end
71
72
  end
72
73
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/utils'
2
4
 
3
5
  module Rack
@@ -68,7 +70,7 @@ module Rack
68
70
  # anything shorter is invalid, this avoids exceptions for common cases
69
71
  # most common being the empty string
70
72
  if since && since.length >= 16
71
- # NOTE: there is no trivial way to write this in a non execption way
73
+ # NOTE: there is no trivial way to write this in a non exception way
72
74
  # _rfc2822 returns a hash but is not that usable
73
75
  Time.rfc2822(since) rescue nil
74
76
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Rack::Config modifies the environment using the block given during
3
5
  # initialization.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/utils'
2
4
  require 'rack/body_proxy'
3
5
 
@@ -15,7 +17,7 @@ module Rack
15
17
  status, headers, body = @app.call(env)
16
18
  headers = HeaderHash.new(headers)
17
19
 
18
- if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
20
+ if !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) &&
19
21
  !headers[CONTENT_LENGTH] &&
20
22
  !headers[TRANSFER_ENCODING] &&
21
23
  body.respond_to?(:to_ary)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/utils'
2
4
 
3
5
  module Rack
@@ -19,7 +21,7 @@ module Rack
19
21
  status, headers, body = @app.call(env)
20
22
  headers = Utils::HeaderHash.new(headers)
21
23
 
22
- unless STATUS_WITH_NO_ENTITY_BODY.include?(status)
24
+ unless STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i)
23
25
  headers[CONTENT_TYPE] ||= @content_type
24
26
  end
25
27
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Regexp has `match?` since Ruby 2.4
4
+ # so to support Ruby < 2.4 we need to define this method
5
+
6
+ module Rack
7
+ module RegexpExtensions
8
+ refine Regexp do
9
+ def match?(string, pos = 0)
10
+ !!match(string, pos)
11
+ end
12
+ end unless //.respond_to?(:match?)
13
+ end
14
+ end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "zlib"
2
4
  require "time" # for Time.httpdate
3
5
  require 'rack/utils'
4
6
 
7
+ require_relative 'core_ext/regexp'
8
+
5
9
  module Rack
6
10
  # This middleware enables compression of http responses.
7
11
  #
@@ -15,19 +19,26 @@ module Rack
15
19
  # directive of 'no-transform' is present, or when the response status
16
20
  # code is one that doesn't allow an entity body.
17
21
  class Deflater
22
+ using ::Rack::RegexpExtensions
23
+
18
24
  ##
19
25
  # Creates Rack::Deflater middleware.
20
26
  #
21
27
  # [app] rack app instance
22
28
  # [options] hash of deflater options, i.e.
23
29
  # 'if' - a lambda enabling / disabling deflation based on returned boolean value
24
- # e.g use Rack::Deflater, :if => lambda { |env, status, headers, body| body.map(&:bytesize).reduce(0, :+) > 512 }
30
+ # e.g use Rack::Deflater, :if => lambda { |*, body| sum=0; body.each { |i| sum += i.length }; sum > 512 }
25
31
  # 'include' - a list of content types that should be compressed
32
+ # 'sync' - determines if the stream is going to be flushed after every chunk.
33
+ # Flushing after every chunk reduces latency for
34
+ # time-sensitive streaming applications, but hurts
35
+ # compression and throughput. Defaults to `true'.
26
36
  def initialize(app, options = {})
27
37
  @app = app
28
38
 
29
39
  @condition = options[:if]
30
40
  @compressible_types = options[:include]
41
+ @sync = options[:sync] == false ? false : true
31
42
  end
32
43
 
33
44
  def call(env)
@@ -52,33 +63,34 @@ module Rack
52
63
  case encoding
53
64
  when "gzip"
54
65
  headers['Content-Encoding'] = "gzip"
55
- headers.delete(CONTENT_LENGTH)
56
- mtime = headers.key?("Last-Modified") ?
57
- Time.httpdate(headers["Last-Modified"]) : Time.now
58
- [status, headers, GzipStream.new(body, mtime)]
66
+ headers.delete('Content-Length')
67
+ mtime = headers["Last-Modified"]
68
+ mtime = Time.httpdate(mtime).to_i if mtime
69
+ [status, headers, GzipStream.new(body, mtime, @sync)]
59
70
  when "identity"
60
71
  [status, headers, body]
61
72
  when nil
62
73
  message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found."
63
74
  bp = Rack::BodyProxy.new([message]) { body.close if body.respond_to?(:close) }
64
- [406, {CONTENT_TYPE => "text/plain", CONTENT_LENGTH => message.length.to_s}, bp]
75
+ [406, { 'Content-Type' => "text/plain", 'Content-Length' => message.length.to_s }, bp]
65
76
  end
66
77
  end
67
78
 
68
79
  class GzipStream
69
- def initialize(body, mtime)
80
+ def initialize(body, mtime, sync)
81
+ @sync = sync
70
82
  @body = body
71
83
  @mtime = mtime
72
- @closed = false
73
84
  end
74
85
 
75
86
  def each(&block)
76
87
  @writer = block
77
- gzip =::Zlib::GzipWriter.new(self)
78
- gzip.mtime = @mtime
88
+ gzip = ::Zlib::GzipWriter.new(self)
89
+ gzip.mtime = @mtime if @mtime
79
90
  @body.each { |part|
80
- gzip.write(part)
81
- gzip.flush
91
+ len = gzip.write(part)
92
+ # Flushing empty parts would raise Zlib::BufError.
93
+ gzip.flush if @sync && len > 0
82
94
  }
83
95
  ensure
84
96
  gzip.close
@@ -90,9 +102,8 @@ module Rack
90
102
  end
91
103
 
92
104
  def close
93
- return if @closed
94
- @closed = true
95
105
  @body.close if @body.respond_to?(:close)
106
+ @body = nil
96
107
  end
97
108
  end
98
109
 
@@ -101,14 +112,14 @@ module Rack
101
112
  def should_deflate?(env, status, headers, body)
102
113
  # Skip compressing empty entity body responses and responses with
103
114
  # no-transform set.
104
- if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
105
- headers[CACHE_CONTROL].to_s =~ /\bno-transform\b/ ||
115
+ if Utils::STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) ||
116
+ /\bno-transform\b/.match?(headers['Cache-Control'].to_s) ||
106
117
  (headers['Content-Encoding'] && headers['Content-Encoding'] !~ /\bidentity\b/)
107
118
  return false
108
119
  end
109
120
 
110
121
  # Skip if @compressible_types are given and does not include request's content type
111
- return false if @compressible_types && !(headers.has_key?(CONTENT_TYPE) && @compressible_types.include?(headers[CONTENT_TYPE][/[^;]*/]))
122
+ return false if @compressible_types && !(headers.has_key?('Content-Type') && @compressible_types.include?(headers['Content-Type'][/[^;]*/]))
112
123
 
113
124
  # Skip if @condition lambda is given and evaluates to false
114
125
  return false if @condition && !@condition.call(env, status, headers, body)
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
  require 'rack/utils'
3
5
  require 'rack/mime'
6
+ require 'rack/files'
4
7
 
5
8
  module Rack
6
9
  # Rack::Directory serves entries below the +root+ given, according to the
@@ -8,7 +11,7 @@ module Rack
8
11
  # will be presented in an html based index. If a file is found, the env will
9
12
  # be passed to the specified +app+.
10
13
  #
11
- # If +app+ is not specified, a Rack::File of the same +root+ will be used.
14
+ # If +app+ is not specified, a Rack::Files of the same +root+ will be used.
12
15
 
13
16
  class Directory
14
17
  DIR_FILE = "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>"
@@ -41,9 +44,9 @@ table { width:100%%; }
41
44
 
42
45
  class DirectoryBody < Struct.new(:root, :path, :files)
43
46
  def each
44
- show_path = Rack::Utils.escape_html(path.sub(/^#{root}/,''))
45
- listings = files.map{|f| DIR_FILE % DIR_FILE_escape(*f) }*"\n"
46
- page = DIR_PAGE % [ show_path, show_path , listings ]
47
+ show_path = Rack::Utils.escape_html(path.sub(/^#{root}/, ''))
48
+ listings = files.map{|f| DIR_FILE % DIR_FILE_escape(*f) } * "\n"
49
+ page = DIR_PAGE % [ show_path, show_path, listings ]
47
50
  page.each_line{|l| yield l }
48
51
  end
49
52
 
@@ -56,9 +59,9 @@ table { width:100%%; }
56
59
 
57
60
  attr_reader :root, :path
58
61
 
59
- def initialize(root, app=nil)
62
+ def initialize(root, app = nil)
60
63
  @root = ::File.expand_path(root)
61
- @app = app || Rack::File.new(@root)
64
+ @app = app || Rack::Files.new(@root)
62
65
  @head = Rack::Head.new(lambda { |env| get env })
63
66
  end
64
67
 
@@ -86,9 +89,9 @@ table { width:100%%; }
86
89
 
87
90
  body = "Bad Request\n"
88
91
  size = body.bytesize
89
- return [400, {CONTENT_TYPE => "text/plain",
92
+ return [400, { CONTENT_TYPE => "text/plain",
90
93
  CONTENT_LENGTH => size.to_s,
91
- "X-Cascade" => "pass"}, [body]]
94
+ "X-Cascade" => "pass" }, [body]]
92
95
  end
93
96
 
94
97
  def check_forbidden(path_info)
@@ -96,13 +99,13 @@ table { width:100%%; }
96
99
 
97
100
  body = "Forbidden\n"
98
101
  size = body.bytesize
99
- return [403, {CONTENT_TYPE => "text/plain",
102
+ return [403, { CONTENT_TYPE => "text/plain",
100
103
  CONTENT_LENGTH => size.to_s,
101
- "X-Cascade" => "pass"}, [body]]
104
+ "X-Cascade" => "pass" }, [body]]
102
105
  end
103
106
 
104
107
  def list_directory(path_info, path, script_name)
105
- files = [['../','Parent Directory','','','']]
108
+ files = [['../', 'Parent Directory', '', '', '']]
106
109
  glob = ::File.join(path, '*')
107
110
 
108
111
  url_head = (script_name.split('/') + path_info.split('/')).map do |part|
@@ -126,7 +129,7 @@ table { width:100%%; }
126
129
  files << [ url, basename, size, type, mtime ]
127
130
  end
128
131
 
129
- return [ 200, { CONTENT_TYPE =>'text/html; charset=utf-8'}, DirectoryBody.new(@root, path, files) ]
132
+ return [ 200, { CONTENT_TYPE => 'text/html; charset=utf-8' }, DirectoryBody.new(@root, path, files) ]
130
133
  end
131
134
 
132
135
  def stat(node)
@@ -154,9 +157,9 @@ table { width:100%%; }
154
157
  def entity_not_found(path_info)
155
158
  body = "Entity not found: #{path_info}\n"
156
159
  size = body.bytesize
157
- return [404, {CONTENT_TYPE => "text/plain",
160
+ return [404, { CONTENT_TYPE => "text/plain",
158
161
  CONTENT_LENGTH => size.to_s,
159
- "X-Cascade" => "pass"}, [body]]
162
+ "X-Cascade" => "pass" }, [body]]
160
163
  end
161
164
 
162
165
  # Stolen from Ramaze
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
  require 'digest/sha2'
3
5
 
@@ -13,7 +15,7 @@ module Rack
13
15
  # defaults to nil, while the second defaults to "max-age=0, private, must-revalidate"
14
16
  class ETag
15
17
  ETAG_STRING = Rack::ETAG
16
- DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze
18
+ DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate"
17
19
 
18
20
  def initialize(app, no_cache_control = nil, cache_control = DEFAULT_CACHE_CONTROL)
19
21
  @app = app